How to Register Interests using 'ALL_KEYS' in Spring Data GemFire with ClientRegionFactoryBean - spring-data-gemfire

I am going to register interests in ALL_KEYS for my Pivotal GemFire client via Spring Data GemFire, but I find that ClientRegionFactoryBean has one method.
org.springframework.data.gemfire.client.ClientRegionFactoryBean.setInterests(Interest<MyRegionPojo>[] interests)
In this case, I only can set the exact keys, but I want to register interests for all keys. My key is not a simple class like String, or Long, but a complex object MyRegionPojo.
Please help if any method to implement so like GemFire API region.registerInterest("ALL_KEYS");

You problem statement is a bit vague but I assume/suspect you are configuring your Spring (Data GemFire) (SDG) application using Spring JavaConfig?
However, I will quickly add that this is not unlike how you would register interests in all keys using SDG's XML namespace, as shown here.
The JavaConfig approach is similar, but clearly based on "strongly-typed arguments", namely 1 or more sub-type instances of the o.s.d.g.client.Interest class to the o.s.d.g.client.ClientRegionFactoryBean.setInterests(:Interest<K>[]) method.
By way of example, you might do the following...
#Bean("Example")
public ClientRegionFactoryBean<?, ?> exampleRegion(GemFireCache gemfireCache) {
ClientRegionFactoryBean<MyRegionKey, MyRegionValue> exampleRegion =
new ClientRegionFactoryBean<>();
RegexInterest regexInterest = new RegexInterest();
regexInterest.setKey(".*");
exampleRegion.setCache(gemfireCache);
exampleRegion.setShortcut(ClientRegionShortcut.PROXY);
exampleRegion.setInterests(new Interest[] { regexInterest });
exampleRegion.setKeyConstraint(MyRegionKey.class);
exampleRegion.setValueConstraint(MyRegionValue.class);
return exampleRegion;
}
NOTE: updated the example above to reflect the proper way to register (Regex) interests based on SDG 1.9 or earlier. Keep in mind that the `o.s.d.g.client.RegexInterest.getRegex() delegates to getKey() therefore you can set the Regular Expression using setKey(:String) as I have shown above.
Notice the o.s.d.g.client.RegexInterest sub-type registration, which is effectively the same as register interests in "ALL_KEYS", as described here as well.
Hope this helps!
-John

Related

Override Sails.js Waterline intercept Find method

I have a model named Product.
I want configurable across the board filtering for this model.
For example: sails.config.field = 2;
When I do GET /Product I want it to essentially do GET /Product?where={"field": 2}
The above works for blueprint by adding a policy, but I want consistent behavior when I use the waterline ORM
GET /Product
and Product.find() should return the same thing.
I can override the model: Product.find and it would work perfectly... IF there was some way for me to access the underlying find code.
The code I am using to intercept the blueprint is:
if (!req.query.where) {
req.query.where = `{"status":{">":0,">=":${sails.config.catalogVersions.status}}}`;
} else {
const parsedWhere = JSON.parse(req.query.where);
parsedWhere.status = {
'>': 0,
'>=': sails.config.catalogVersions.status,
};
req.query.where = JSON.stringify(parsedWhere);
}
I could very easily apply this to a Model.find interceptor.
Is there any way that once sails is loaded, I can access the root find method on a model even if its been overwritten at load time?
Maybe you could think on something like this one:
https://github.com/muhammadghazali/sails-hook-pagination
It's a hook and maybe works for your intended use.
I ended up using the hook:orm:loaded hook, to run some code which monkeypatched all of the models with a defaultScope which was stored in each of my models. It works well as I can easily modify the default criteria on all of the models and get consistent behavior across blueprint and waterline.
For code see:
Is there a way to override sails.js waterline endpoint with custom controller, but keep built in pagination, and filtering?

How do I get Swashbuckle to have Swagger UI to group by Version?

I am playing with the new Azure API Apps (template in Visual Studio 2013 w/ the new SDK bits from 3/24/15) and I'd like have my Swagger UI group my calls by Version #. In my case, I'm currently versioning by URI (I realize REST purists will tell me not to do this - please don't try to "correct my error" here). For instance, I may have these calls:
http://example.com/api/Contacts <-- "latest"
http://example.com/api/1/Contacts
http://example.com/api/2/Contacts
http://example.com/api/Contacts{id} <-- "latest"
http://example.com/api/1/Contacts/{id}
http://example.com/api/2/Contacts/{id}
Functionally, this works great! (Yes, I know some of you will cringe. Sorry this hurts your feelings.) However, my problem is w/ Swagger UI organization. By default, Swagger UI groups these by the Controller Name (Contacts in this case). I see in the SwaggerConfig.cs file that I can change this:
// Each operation be assigned one or more tags which are then used by consumers for various reasons.
// For example, the swagger-ui groups operations according to the first tag of each operation.
// By default, this will be controller name but you can use the "GroupActionsBy" option to
// override with any value.
//
//c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString());
What I don't understand is how I can tweak this to group all of the "latest" together and then all of v1 together and then all of v2 together, etc.
How can I do this? If it absolutely must require that I add the word "latest" (or equiv) into the path in place of the version number, then I can do that but I'd prefer not have to do that.
I believe what you're looking to do is to uncomment a line a few lines below that one in SwaggerConfig.cs
c.OrderActionGroupsBy(new DescendingAlphabeticComparer());
except you'd change the name of the class to something like ApiVersionComparer() and then implement it as a new class:
public class ApiVersionComparer : IComparer<string>
{
public int Compare(string x, string y)
{
// Write whatever comparer you'd like to here.
// Yours would likely involve parsing the strings and having
// more complex logic than this....
return -(string.Compare(x, y));
}
}
If you've gotten far enough to ask this question, I'm sure I can leave the sort implementation for you. :-)

HATEOAS link to method with optional requestparams

I want to link to a method that has the following signature:
public SomeResponse getSomeObjects(#RequestParam(value = "foo", defaultValue = "bar") Foo fooValue)
Now I want the link to look like this:
http://myhost/api/someobjects
I tried using methodOn from Spring HATEOAS's ControllerLinkBuilder as seen below:
discoverResponse.add(linkTo(methodOn(SomeController.class).getSomeObjects(null)).withRel("someobjects"))
But it doesn't lead to the desired link because a ?foo is added at its end. How can I achieve the above objective?
Since backward compatibility is such an issue for you, you could always manually construct your Link objects like so:
discoverResponse.add(new Link(baseUri() + "/someobjects", "someobjects"));
The other option would be to fork Spring HATEOAS on GitHub, build the project yourself, and change the way defaults are handled in ControllerLinkBuilder. I don't really know how you'd expect an out-of-context Link builder to be able to differentiate between whether it should advertise an optional parameter. In the HATEOAS world, if the parameter isn't included, the client doesn't know about it. So why even have the optional parameter?
I know there are 7 years gone now, but I had a similar problem today which lead me here. In spring hateoas 1.1.0 the behavior is slightly different, instead it will generate URI-Templates by default for non-required #RequestParams:
http://myhost/api/someobjects{?foo}
If you don't want them in your link, you can just expand it
Map<String, Object> parameters = new HashMap<>();
parameters.put("foo", null);
link = link.expand(parameters);
It will result in the desired URL
http://myhost/api/someobjects

Dynamic mask data for web project

Currently our web projects need to anonymize some data.
(for example a security number like 432-55-1111 might appear as 432-55-**)
These datas may contain email, id, price, date ,and so on.
The tables' name and columns that needed to be masked was saved in DB.
We are using spring security to judge a user whether he can see the data or not.
The data domain object(CMP) may be get from SQL or JPQL(named query or native query)or JPA Load method or Mainframe.
We need to find a best efficient way (not the DB end) to mask these data dynamically.
If we use a interceptor at the EJB method end , we need to annotation all the Object(DTO)
and all the columns. That's may be low efficiency.
Any body know how can we invoke a method(like a interceptor) when finish SQL executed and named query(native query) exectued, and we can call a method to mask the result by the query and user id.
Or other ways.
It would be good to have this in the lowest level, so that other applications like reporting would not need a separate solution.
Our project's architecture is JSF+Spring+EJB 3.0+JPA 1.0.We have many web projects.For JPA some projects using EclipseLink 2.2 ,some using Hibernate.
UPDATE:
More information about our projects. We have many web project about different feature.So we have many ejb projects associated with them. Every ejb has DAO to get their CMP by call JPQL or get(class, primarykey) metod.Like below:
Query query = em.createNamedQuery(XXXCMP.FIND_XXX_BY_NAME);
query.setHint(QueryHints.READ_ONLY, HintValues.TRUE);
query.setParameter("shortName", "XXX").getSingleResult();
Or
XXXCMP screen = entityManager.find(XXXCMP.class, id);
The new EJB services code converter to transfrom the data from CMP to DTO.
The converter as below:
/**
* Convert to CMP.
*
*/
CMP convertToCMP(DTO dto, EntityManager em);
/**
* Convert CMP to domain object with all fields populated, the default scenario is
* <code>EConvertScenario.Detail</code>.
*
*/
DTO convertFromCMP(CMP cmp, EntityManager em);
But some old services use their own methods to convert CMP.Also some domain services used for search lazy paing, they also don't use the converter.
We want to mask the data before the CMP convert to DTO.
You can try EntityListener to intercept entity loading into the persistence context with #PostLoad annotation.
Else, can try within accesor methods(getter/setter) which I think is suitable for masking/formatting etc.
Edit : (based on comments & question update)
You can share entity/DTO across appications
public String getSomethingMasked(){
return mask(originalString);
}
The data retrieval pattern isn't uniform across applications. If all the applications are using same database, it must be generalized. There is no point of writing same thing again with different tools. Each application might apply business logic afterwards.
Probably, you can have a separate project meant for interacting with database & then including it in other applications for further use. So it will be a common point to change anything, debug, enhance etc.
You are using Eclipselink, Hibernate & other custom ways for fetching data & you require minimal workaround, which from my perspective seems difficult.
Either centralize the data retrieval or make changes all over separately if possible, which I think is not feasible, compromising consistency.
In this case, you may intercept the JSF's conversion fase. This solution applies to JSF views, not to reportings.
#FacesConverter("AnonymizeDataConverter")
public class AnonymizeDataConverter implements Converter{
#Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return getAnonymisedData(value);
}
#Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
return getAnonymisedData(value);
}
public static String getAnonymisedData(Object data) {
if (data == null)
return "";
String value = data.toString().trim();
if (!value.isEmpty())
return value.substring(0, value.lenght() - 4) + "**";
return "";
}
}

How to obtain wicket URL from PageClass and PageParameters without running Wicket application (i.e. without RequestCycle)?

In my project, there are additional (non-wicket) applications, which need to know the URL representation of some domain objects (e.g. in order to write a link like http://mydomain.com/user/someUserName/ into a notification email).
Now I'd like to create a spring bean in my wicket module, exposing the URLs I need without having a running wicket context, in order to make the other application depend on the wicket module, e.g. offering a method public String getUrlForUser(User u) returning "/user/someUserName/".
I've been stalking around the web and through the wicket source for a complete workday now, and did not find a way to retrieve the URL for a given PageClass and PageParameters without a current RequestCycle.
Any ideas how I could achieve this? Actually, all the information I need is somehow stored by my WebApplication, in which I define mount points and page classes.
Update: Because the code below caused problems under certain circumstances (in our case, being executed subsequently by a quarz scheduled job), I dived a bit deeper and finally found a more light-weight solution.
Pros:
No need to construct and run an instance of the WebApplication
No need to mock a ServletContext
Works completely independent of web application container
Contra (or not, depends on how you look at it):
Need to extract the actual mounting from your WebApplication class and encapsulate it in another class, which can then be used by standalone processes. You can no longer use WebApplication's convenient mountPage() method then, but you can easily build your own convenience implementation, just have a look at the wicket sources.
(Personally, I have never been happy with all the mount configuration making up 95% of my WebApplication class, so it felt good to finally extract it somewhere else.)
I cannot post the actual code, but having a look at this piece of code will give you an idea how you should mount your pages and how to get hold of the URL afterwards:
CompoundRequestMapper rm = new CompoundRequestMapper();
// mounting the pages
rm.add(new MountedMapper("mypage",MyPage.class));
// ... mount other pages ...
// create URL from page class and parameters
Class<? extends IRequestablePage> pageClass = MyPage.class;
PageParameters pp = new PageParameters();
pp.add("param1","value1");
IRequestHandler handler = new BookmarkablePageRequestHandler(new PageProvider(MyPage.class, pp));
Url url = rm.mapHandler(handler);
Original solution below:
After deep-diving into the intestines of the wicket sources, I was able to glue together this piece of code
IRequestMapper rm = MyWebApplication.get().getRootRequestMapper();
IRequestHandler handler = new BookmarkablePageRequestHandler(new PageProvider(pageClass, parameters));
Url url = rm.mapHandler(handler);
It works without a current RequestCycle, but still needs to have MyWebApplication running.
However, from Wicket's internal test classes, I have put the following together to construct a dummy instance of MyWebApplication:
MyWebApplication dummy = new MyWebApplication();
dummy.setName("test-app");
dummy.setServletContext(new MockServletContext(dummy, ""));
ThreadContext.setApplication(dummy);
dummy.initApplication();