Liferay model listener ordering - liferay

Following is my requirement :
Whenever site is created, with help of GroupListener we are adding some custom attributes to created site.
So assume that you are crating "Liferay Test" site then it will have some fix custom attribute "XYZ" with value set in GroupListeners onAfterCreate method.
I can see this value in custom fields under site settings.
Now based on this values, we are creating groups in another system(out of liferay, using webservices).
So far so good.
Whenever we are deleting the site we need to remove the equivalent groups from other system via web service.
But while deleting site, in GroupListener we are not able to retrieve the custom attributes.
On further debug by adding expando listener, I observed that Expando listeners are getting called first and then delete method of GroupLocalService/GroupListener.
And hence we are not able to delete the groups present in another system.
So I was wondering if we can have ordering defined for listeneres.
Note: Since we were not getting custom attributes in listeners we implemented GroupLocalServiceImpl and with this we are getting custom attributes in delete method on local environment but not on our stage environment which has clustering.

You shouldn't use the ModelListeners for this kind of change, rather create ServiceWrappers, e.g. wrap the interesting methods in GroupLocalService (for creation as well as deletion).
This will also enable you to react to failures to create records in your external system etc.

Related

The Blazor Way to "share" an object among components, routes, pages, etc

My application will have the user open a file that will be read by the application, and that file will contain database information that will be stored into an object.
The way I see a Blazor app now is that MainLayout.razor is the component that renders my full page: the navbar and the #Body. I would like the file name I grab from the open dialog box to be passed to my project where I then create my object and fill it with the file information.
I got working where I created the object in one of the blazor component modules, only to realize that I would need to do this for all my modules, that is read and parse my database into an object everytime the user clicks a new tab to load a new component. I would like this reading and parsing of the database to be done once, stored in my object and have that object be available to all potential blazor components in my project.
Where should I define the instance of my object and how should I make that object seen and even be updated by all other components? Is this even possible? Am I passing this object as a parameter, is it part of my routing. I'm not sure how to go about this.
Three ways:
State Class
Create a class with the properties you want to share. Make the class observable. Don't use property setters to change the values, use a method, that not only updates the state it notifies listeners of the change.
This class is provided for injection in program.cs
Cascading Value
Same as the state class but presented as a cascading value instead of injection. This has the added advantage of being able to scope the listeners of the value within the html hierarchy.
Local or Session Storage
Use JSInteropt to save values to sessions/local storage. The relevant components need to listen for updates and read the storage.
As you have not provided any code or shown any attempt I only listed a broad outline of ways achieve this. In my opinion for your scenario, option 1 is the best choice.
The link you suggested has no way of notifying listeners. The components will not react to changes that occur after initialising.

Adding custom attribute in all spring integration component

I need to add custom attribute to all spring integration component for example - need to add 'description' attribute to all inbound and outbound gateway.
Once we are able to add the custom attribute, I need to log the newly added attribute - 'description'.
Can you please suggest the approach for this.
Thanks
I've explained you how it isn't going to be possible because if Java nature. Now let's try to imagine what we could do on the matter. You can register some additional support beans in the application context and have their relationship to the integration components. For example through some id pattern or key-value store like simple HashMap. So, this way you always will be able to extract that additional information whenever you get access to the original component: or rely on its id or call the map registry.

How to retreive endpoint of a service

i want to add my project's endpoint in the project tear down script. What is the syntax in order to get the endpoint for all requests and test requests as the user will assign their endpoint via all requests and test requests before running the project?
i seen an example using test step but i don't want to retrieve it via the test step route:
testRunner.testCase.getTestStepByName("dd").getHttpRequest().getEndpoint();
The tear down script use either , log, context, runner nd project variables.
Thanks
Based on the information updated in the question, it looks like you have to access the endpoint in the TearDown Script of the project.
It also appears that you would need to execute the same set of tests against different base url of the endpoint and domain. Not sure even you might need to use the credentials accordingly.
Considering the above, it would be easy to project level properties.
Here you would go:
Create a project level custom property for base url, say BASE_URL as property name and value as http://10.0.0.1:8008. Of course, change it with actual value as needed with respect to the tests to be executed.
Similarly create another project level property for domain, say DOMAIN_NAME and provide its value according the test.
Double click on service / interface, click on Service Endpoints tab.
Remove all the existing values.
Add a new endpoint by clicking + icon.
Add ${#Project#BASE_URL} as endpoint and ${#Project#DOMAIN_NAME} as domain values
If required, you use the same approach for the credentials.
Now click on Assign button there and choose All requests and Tests option from the dropdown.
Similarly, do the same if you have multiple services / interfaces.
How to access the above values in TearDown Script?
log.info "Endpoint : ${project.getPropertyValue('BASE_URL')}"
log.info "Domain : ${project.getPropertyValue('DOMAIN_NAME')}"
When you want to change domain or base url, just change the values of the respective project properties before you run execute the tests against different servers / environments.
EDIT:
The values for the endpoint or domain can passed dynamically (without even changing value saved in the project) from command line using SOAPUI_HOME/bin/testrunner utility while executing the tests. For more details, refer documentation

MVCSiteMapProvider overriding GetDynamicNodeCollection with multiple requests

I am using MVCSiteMapProvider for MVC5. I have created my own implementation of DynamicNodeProviderBase to dynamically create nodes in my site map based on a collection of categories for our product catalogue.
I am using SimpleInjector and have a MvcSiteMapProviderContainerInitializer that I pull from the sample project for the site map provider. This is working fine.
However, when calling Html.MvcSiteMap().SiteMapPath() this results a call to GetDynamicNodeCollection for every request. Can the dynamic node collection be done once per lifetime of the container rather then on a per request basis?
Thanks in advance
The class I have implemented is actually created as a singleton, so for now I have initialised the nodes collection from within the constructor. This will do now.
However, I saw this blog post from 2012 but the interface seems to have changed in later versions of the provider so this is no longer possible
http://xharze.blogspot.co.uk/2012/04/inside-mvcsitemapprovider-part-2.html?m=1

Apply IHasRequestFilter to Plugin registered service dynamically

I have a set of Services that I want to use in various ServiceStack projects (okay, two) so I have created a ServiceStack Plugin that registers them.
However I want to allow users to determine their own method of securing access to these services.
Currently I have an IHasRequestFilter in one my projects that can determine which services a user should be able to access. I do not want a reference to this in the Plugin project, so I want to add this dynamically after the fact.
I want to somehow get a reference to the Service Definition in AppHost to add this IHasRequestFilter to the pipeline for a specific set of services.
Ideally I should be able to do something like this:
new CustomPlugin(new CustomPluginParams {
RestrictTo = CustomRestrictions,
RequestFilters = [],
ResponseFilters = []
});
This should use those properties to configure their services without having a previous typed reference.
Edit:
Investigating further it appears that the IHasRequestFilter and IHasResponseFilters are only parsed once, in the ServiceExec<TService> class. I could get round this by creating my Services with a Proxy which adds the attribute I require to the MemberInfo of the operations, however I don't regard that as a clean approach.
Does anyone have recommendation?
In ServiceStack all configuration should happen within AppHost's Configure() method and remain immutable thereafter.
Lifecycle Events
To help with LifeCycle events there are IPreInitPlugin and IPostInitPlugin Plugin Interfaces which your Plugins can implement so they will get called back before and after all plugins are registered.
There's also an IAppHost.AfterInitCallbacks plugins can use to get called back after the entire AppHost has finished initialiazing.
Typed Request/Response Filters
Attributes are typically statically defined on Services, to dynamically add logic that apply to specific Request/Responses you can use a typed Request/Response filter.
The nice thing about ServiceStack Filters is that they share the same API (IRequest, IResponse, object) which makes them easily composable, e.g:
RegisterTypedRequestFilter<CustomRequest>(new RequestAttributeFilter().Execute);
Dynamically adding Attribute filters
As all ServiceStack libraries use ServiceStack.Text's Reflection API's you're able to extend ServiceStack's attribute-based code-first API dynamically by adding attributes to types or properties at runtime, e.g:
typeof(CustomRequest)
.AddAttributes(new RuntimeAttributeRequestFilter());
This can be done for most of ServiceStack's code-first API's inc. Request/Response Filters.
Route attributes and Action Filters
There is sometimes an issue for Services Route attributes and Action filters that already pre-configured and autowired before the AppHost's Configure() is called.
One solution is to add them in the AppHost constructor (or by overriding AppHost.OnBeforeInit) so they're added before the Services are configured. Otherwise you can reset the action filter caches by calling the AppHost's ServiceController.ResetServiceExecCachesIfNeeded().

Resources