Two Applications using the same index file with Hibernate Search - java

I want to know if it is possible to use the same index file for an entity in two applications. Let me be more specific:
We have an online Application with a frondend for the users and an application for the backend tasks (= administrator interface). Both are running on the same JBOSS AS. Both Applications are using the same database, so they are using the same entities. Of course the package names are not the same in both applications for the entities.
So this is our usecase: A user should be able to search via the frondend. The user is only allowed to see results which are tagged with "visible". This tagging happens in our admin interface, so the index for the frontend should be updated every time an entity is tagged as "visible" in the backend.
Of course both applications do have the same index root folder. In my index folder there are 2 index files:
de.x.x.admin.model.Product
de.x.x.frondend.model.Product
How to "merge" this via Hibernate Search Configuration? I just did not get it via the documentation...
Thanks for any help!

Ok, it seems, that this is not possible...

Related

Google App Engine Guestbook example index not working

I have checked out Googles code example for the Guestbook. It builds locally and I can deploy it to my local machine and it is working out ok.
When I try to deploy it to Google App Engine this happens in the log:
com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found. recommended index is:
- kind: Greeting
ancestor: yes
properties:
- name: date
direction: desc
The suggested index for this query is:
<datastore-index kind="Greeting" ancestor="true" source="manual">
<property name="date" direction="desc"/>
</datastore-index>
at com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:56)
After a bit of Googling I find people that suggest one of two things. 1) Do some editing in the YAML. 2) Manually modify the TARGET and add some index config.
I'd like to avoid both because 1) In the latest Guestbook code sample there is no YAML and 2) I prefer to automate my build than to manually hack it every time I want to deploy.
Is there any way to make this work when using mvn appengine:deploy ?
This is the guide I have been using : https://cloud.google.com/appengine/docs/standard/java/tools/using-maven
It's perfectly normal (sometimes even required) to manually modify the datastore index configuration file according to your app's specific usage. The reason for which such file may be missing from the sample code could be that it is typically auto-generated. From Cloud Datastore Indexes:
Important: For an in-depth discussion of indexes and querying, see the article Index Selection and Advanced Search.
App Engine predefines a simple index on each property of an entity. An
App Engine application can define further custom indexes in an index
configuration file named datastore-indexes.xml, which is
generated in your application's /war/WEB-INF/appengine-generated
directory . The development server automatically adds suggestions to
this file as it encounters queries that cannot be executed with the
existing indexes. You can tune indexes manually by editing the file
before uploading the application.
You should also note that the datastore index configuration is an app-level configuration, shared by all app's services/modules, even if they're not written in Java. Which is why you may see references to both datastore-indexes.xml (java-only, the suggested index format in your message is for this file) and index.yaml (all languages).
Another important note is that the index configuration can be deployed independently from the service/module code, including with maven. From App Engine Maven Plugin Goals and Parameters:
appengine:deployIndex
Deploys an index.yaml configuration file to App Engine.
So just use this target to update your datastore index configuration.

How to migrate database on multi-node production server?

I have a multi-node production server (Tomcat 8.x on CentOS 7.x; each node is a separate CentOS instance), that uses a single MySQL database server (MySQL 5.7.x). Each node of the server will be updated manually: system administrator stops each node and deploys a new version of the application (.war file). It means that the service won't have downtime, because at every moment there is at least one working node.
Database migrations are implemented using Liquibase changesets, which are placed in the .war file. So each node validates and updates (if requires) the database schema. Actually, only the first node executes changesets and other nodes just validate it.
The problem is that there is a time gap between updates of each node: when the first node is already updated with the new application version, the last node still works on the previous application version (that might use old columns in database for example). It might lead to inconsistency of the database.
Example
Let's say the server has 3 nodes. At this moment they work on an application of version N.
Next releases need to change a database schema: rename a column title to title_new.
To make it possible to update database schema without downtime, we need to use "two-steps change":
version N+1:
adds a new column title_new,
doesn't use a column title anymore (it's marked as deprecated);
copy all data from the column title to title_new;
uses a column title_new;
version N+2 drops a column title.
Now administrator is going to deploy version N+1. He stops the first node for update, but the other two nodes are still working on the version N. While the first node is updating, some users might change their data using node 2 or 3 (there is a load balancer, that routes requests to different nodes). So we need a way to forbid users to make any changes via nodes 2 and 3, while they are not updated with a version N+1.
I see two different ways to solve this problem:
Use some read_only mode on the application level - then the application logic forbids users to make any changes. But then we need to implement some ways to enable this mode at any time using a console or admin panel (administrator must be allowed to enable this mode).
Use read_only mode on database level. But I couldn't find any ready-for-use methods for MySQL to do this.
The question: what's the best way to solve the described issue?
P.S. Application is based on the Spring 4.x framework + Hibernate 4.x.
An alternative way of solving this may be: "using database trigger":
version N+1 :
for every renamed column create a trigger that copy data inserted/updated in title to title_new (see here)
version N+2 :
Drop the trigger, drop the old column
The advantage of this approach are:
it can be done completely with liquibase (don't need additional steps for the administrator)
all your nodes remains fully functional (no read-only)
The drawbacks :
you must write/use triggers
can be tricky if your db updates are more complex (like column renamed + new db-constraints)
Zero Downtime Deployment with a Database
I found the above article to be very insightful as to the various options for database migrations without downtime.

Get most recent ldap entry

I'm running into an issue currently that I can't seem to figure out. I'm attempting to write an LDAP query that retrieves the most recent entry in a directory. There doesn't seem to be native functionality to do this, and all information I'm finding requires other information about the sought after entry to be known.
If I were using a database, I could just sort the entries by 'dateCreated' and limit the results to 1, however with an LDAP query to a Directory Server, I don't believe that's possible.
Any tips/advice would be greatly appreciated, thanks!
LDAP RFC 4512 defines a standard attribute named createTimestamp that is automatically set by the server on every object created in the directory. It also defines modifyTimestamp for update operations.
Since these are operational attribute, they will only be returned when you query the server if you explicitly include them in the object attribute list to retrieve
Some LDAP servers like Redhat Directory Server support server-side sorting so you can also use these attributes as your sort criteria.
On a large directory deployment , you should make sure that server indexes are created for these attributes to achieve reasonable query performance.

Different environments configuration on Google AppEngine

I have a web-application running on Google AppEngine.
I have a single PRODUCTION environment, a STAGING env and multiple development & QA envs. There are many configuration parameters that should differ between PRODUCTION and other environments - such as API keys for services we integrate with (GoogleAnalytics for example). Some of those parameters are defined in code, other are defined in web.xml (inside init-param tag for Filters, for example), and others cases as well.
I know that there are a couple of approaches to do so:
Saving all parameters in the datastore (and possible caching them in each running instance / Memcached)
Deploying the applications with different system-properties / environment-variables in the web.xml
Other options...?
Anyway, I'm interested to hear your best-practices for resloving this issue.
My favorite approach is to store them all in datastore and having only one master record in it with all the different properties and making a good use of the memcache. By doing that you don't need to have different configuration files or polluting your code with different configuration settings. Instead you can deploy and change this values from an administrative form that you will have to create in order to update this master record.
Also if you are storing tokens and secret keys then you are aware of the fact that is definitely not a good idea to have them in the web.xml or anywhere else in the code, but rather having it per application on something more secure, like datastore.
Once you have that, then you can have one global function that will retrieve properties by name and if you want to get the Google Analytics ID from anywhere in your app you should use it by having something like this:
getProperty('googleAnalyticsID')
where this global getProperty() function will try to find this value with these steps:
Check if it exist in memcache and return
If not in memcache, update memcache from master entity from datastore and return
If not in datastore create an entity with a default values, update memcache and return
Of course there are different approaches on how to retrieve data from that Model but the idea is the same: Store in one record and use the memcache.
You must have separate app ids for your production/staging/qa envs. This must be hardcorded into your web.xml (or you have a script of some sort that updates your web.xml)
After that you can code in your settings based on appid. I assume there's a java equivalent to this:
https://developers.google.com/appengine/docs/python/appidentity/functions#get_application_id
You could put it in the datastore if they're settings that change dynamically, but if they are static to the environment, it doesn't make sense to keep fetching from datastore.

What causes duplicate requests to occur using spring,tomcat and hibernate

I'm working on a project in Java using the spring framework, hibernate and tomcat.
Background:
I have a form page which takes data, validates, processes it and ultimately persists the data using hibernate. In processing the data I do some special command (model)
manipulation prior to persisting using hibernate.
Problem:
For some reason my onSubmit method is being called twice, the first time through things
are processed properly. However the second time through they are not; and the incorrect
information is being persisted.
I've also noticed that on other pages which are simply pulling information from the data
base and displaying on screen; Double requests are happening there too.
Is there something misconfigured, am I not using spring properly..any help on this would
be great!
Additional Information:
The app is still being developed. In testing the app I'm running into this problem. I'm using the app as I would expect it to be used (single clicks,valid data,etc...)
If you are testing in IE, make note that in some versions of IE it sometimes submits two requests. What browsers are you testing the app in?
There is the javascript issue, if an on click handler is associated with submit button and calls submit() and does not return false to cancel the event bubble.
Could be as simple as users clicking on a link twice, re-submitting a form while the server is still processing the first request, or hitting refresh on a POST-ed page.
Are you doing anything on the server side to account for duplicate requests such as these from your users?
This is a very common problem faced by someone who is starting off. And not very sure about the application eco-system.
To deploy a spring app, we build the war file.
Then we put it inside 'webapps' folder of tomcat.
Then we run the tomcat instance using terminal (I am presuming a linux system).
Now, we set up env in that terminal.
The problem arises when we set up our environment for the spring application where there can be more than one war files to be deployed.
Then we must cater to the fact that the env must be exclusive to a specific war file.
To achieve this, what we can do is create exclusive env files for every war. (e.g. war_1.sh,war_2.sh,.....,war_n.sh) and so on.
Now we can source that particular env file for which we have to deploy its corresponding war. This way we can segregate the multiple wars (applications) and their environment.

Categories