I'm working on a webapp running on Tomcat which using spring-data to connect to a neo4j graph in embedded mode.
I would like to use neo4j server instead of the embedded mode and I am looking for some help to be sure about how to do that.
Some of my application services are quite difficult and combine, in a single transaction, the result of several cypher requests in a dto sent back to the user.
First I thought that I have to create a server unmanaged extension and I think I should follow these following steps.
- Keep my webapp with springMVC and spring security to hold and secure users sessions.
- Regroup all my transactional services in a specific jar my-app.jar
- Use Jax-RS to add a REST access point on each of my service of my-app.jar
- use something like spring restTemplate from my spring controller to call services from my-app.jar
First question : is this way of doing things is the good way ?
Second question : I have many spring injection in my services layer. How can I keep them working (how can I add dependencies in the server extension ?
Then I discovered graphAware and I wonder if I should use it instead.
And finally I just read this post http://jexp.de/blog/2014/12/spring-data-neo4j-improving-remoting-performance/ and it seems that I should use
the SpringCypherRestGraphDatabase (as explain in the bold text at the end of the article).
Well, I'm a little bit lost and I would appreciate any help to use neo4j server instead the embedded mode for my application which contain some complexe transactions.
You have a number of options here and you are on the right track with your thinking.
Option 1:
If your use cases are business-logic-heavy, and your question suggests that they are, going the unmanaged extension route is one option.
Essentially, you can then combine the most performant Java API and Cypher (if you wish) to perform your use case. I wouldn't use SDN here by the way, so you have to do your mapping manually, but is there really any mapping? Maybe you just want to execute traversals / Cypher queries for each one of your use cases.
Each use case then exposes a simple REST API, which is consumed by your Spring-powered application running Spring MVC, Spring Security, and all that. You can use the RestTemplate from Spring in your app's Controllers.
To add a twist to all that, you can use the GraphAware Framework to develop the "unmanaged extension" using Spring MVC as well. That would be my preferred option, knowing nothing about your domain/app.
Option 2:
Use the new version of SDN (v4) as Michael suggests. This allows you to run your application with annotated domain objects, Spring MVC, Security, et al. Operations (CRUD and other) are automatically translated to Cypher and sent across the wire to Neo4j running in server mode (no extensions needed). Results are then marshalled back to Java objects.
We're about to release Milestone 1 of SDN v4. It shouldn't take more than a week. That said, it is still going to be a Milestone release, thus not ready for production. A GA release is expected in May (ish).
You can already try SDN v4 yourself. Clone this repo: https://github.com/spring-projects/spring-data-neo4j, make sure you're on the 4.0 branch, and do an mvn clean install on it. Here's a sample app, built using Angular JS and Spring Boot.
Please do get in touch with feedback / questions / problems (best by email info at graphaware dot com). Cheers!
I suggest you wait a bit until SDN4 Milestone 1 comes out (developed by GraphAware) this was written from scratch for Neo4j-Server.
I need to integrate a standalone Apache Solr server to my grails application. I know there is a solr plugin for grails, but it embeds the solr server and the plugin don't seem to actively maintained.
My main question is how to index the fields in my domain objects. I want to update the index when I create/update/delete my domain objects. I guess it can be done via a afterInsert/afterUpdate/afterDelete event. But there must be some smarter (=less code in the domain objects) way of doing this?
You can register an hibernate event listener, or use a event publishing/listeningn mechanism like this -> http://grailsrocks.github.io/grails-platform-core/guide/events.html
Then, when your domain objects are changed, just update them in the solr, using solr plugin
What is JNDI?
What is its basic use?
When is it used?
What is JNDI ?
It stands for Java Naming and Directory Interface.
What is its basic use?
JNDI allows distributed applications to look up services in an abstract, resource-independent way.
When it is used?
The most common use case is to set up a database connection pool on a Java EE application server. Any application that's deployed on that server can gain access to the connections they need using the JNDI name java:comp/env/FooBarPool without having to know the details about the connection.
This has several advantages:
If you have a deployment sequence where apps move from devl->int->test->prod environments, you can use the same JNDI name in each environment and hide the actual database being used. Applications don't have to change as they migrate between environments.
You can minimize the number of folks who need to know the credentials for accessing a production database. Only the Java EE app server needs to know if you use JNDI.
What is JNDI ?
The Java Naming and Directory InterfaceTM (JNDI) is an application programming interface (API) that provides naming and directory functionality to applications written using the JavaTM programming language. It is defined to be independent of any specific directory service implementation. Thus a variety of directories(new, emerging, and already deployed) can be accessed in a common way.
What is its basic use?
Most of it is covered in the above answer but I would like to provide architecture here so that above will make more sense.
To use the JNDI, you must have the JNDI classes and one or more service providers. The Java 2 SDK, v1.3 includes three service providers for the following naming/directory services:
Lightweight Directory Access Protocol (LDAP)
Common Object Request Broker Architecture (CORBA) Common Object Services (COS) name service
Java Remote Method Invocation (RMI) Registry
So basically you create objects and register them on the directory services which you can later do lookup and execute operation on.
JNDI in layman's terms is basically an Interface for being able to get instances of internal/External resources such as
javax.sql.DataSource,
javax.jms.Connection-Factory,
javax.jms.QueueConnectionFactory,
javax.jms.TopicConnectionFactory,
javax.mail.Session, java.net.URL,
javax.resource.cci.ConnectionFactory,
or any other type defined by a JCA resource adapter.
It provides a syntax in being able to create access whether they are internal or external. i.e (comp/env in this instance means where component/environment, there are lots of other syntax):
jndiContext.lookup("java:comp/env/persistence/customerDB");
JNDI Overview
JNDI is an API specified in Java
technology that provides naming and
directory functionality to
applications written in the Java
programming language. It is designed
especially for the Java platform using
Java's object model. Using JNDI,
applications based on Java technology
can store and retrieve named Java
objects of any type. In addition, JNDI
provides methods for performing
standard directory operations, such as
associating attributes with objects
and searching for objects using their
attributes.
JNDI is also defined independent of
any specific naming or directory
service implementation. It enables
applications to access different,
possibly multiple, naming and
directory services using a common API.
Different naming and directory service
providers can be plugged in seamlessly
behind this common API. This enables
Java technology-based applications to
take advantage of information in a
variety of existing naming and
directory services, such as LDAP, NDS,
DNS, and NIS(YP), as well as enabling
the applications to coexist with
legacy software and systems.
Using JNDI as a tool, you can build
new powerful and portable applications
that not only take advantage of Java's
object model but are also
well-integrated with the environment
in which they are deployed.
Reference
What is JNDI ?
JNDI stands for Java Naming and Directory Interface. It comes standard with J2EE.
What is its basic use?
With this API, you can access many types of data, like objects, devices, files of naming and directory services, eg. it is used by EJB to find remote objects. JNDI is designed to provide a common interface to access existing services like DNS, NDS, LDAP, CORBA and RMI.
When it is used?
You can use the JNDI to perform naming operations, including read operations and operations for updating the namespace. The following operations are described here.
I will use one example to explain how JNDI can be used to configure database without any application developer knowing username and password of the database.
1) We have configured the data source in JBoss server's standalone-full.xml. Additionally, we can configure pool details also.
<datasource jta="false" jndi-name="java:/DEV.DS" pool-name="DEV" enabled="true" use-ccm="false">
<connection-url>jdbc:oracle:thin:#<IP>:1521:DEV</connection-url>
<driver-class>oracle.jdbc.OracleDriver</driver-class>
<driver>oracle</driver>
<security>
<user-name>usname</user-name>
<password>pass</password>
</security>
<security>
<security-domain>encryptedSecurityDomain</security-domain>
</security>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>false</background-validation>
<background-validation-millis>1</background-validation-millis>
</validation>
<statement>
<prepared-statement-cache-size>0</prepared-statement-cache-size>
<share-prepared-statements>false</share-prepared-statements>
<pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>10</max-pool-size>
</pool>
</statement>
</datasource>
Now, this jndi-name and its associated datasource object will be available for our application.application.
2) We can retrieve this datasource object using JndiDataSourceLookup class.
Spring will instantiate the datasource bean, after we provide the jndi-name.
Now, we can change the pool size, user name or password as per our environment or requirement, but it will not impact the application.
Note : encryptedSecurityDomain, we need to configure it separately in JBoss server like
<security-domain name="encryptedSecurityDomain" cache-type="default">
<authentication>
<login-module code="org.picketbox.datasource.security.SecureIdentityLoginModule" flag="required">
<module-option name="username" value="<usernamefordb>"/>
<module-option name="password" value="894c8a6aegc8d028ce169c596d67afd0"/>
</login-module>
</authentication>
</security-domain>
This is one of the use cases. Hope it clarifies.
A naming service associates names with objects and finds objects based on their given names.(RMI registry is a good example of a naming service.) JNDI provides a common interface to many existing naming services, such as LDAP, DNS.
Without JNDI, the location or access information of remote resources would have to be hard-coded in applications or made available in a configuration. Maintaining this information is quite tedious and error prone.
The best explanation to me is given here
What is JNDI
It is an API to providing access to a directory service, that is, a service mapping name (strings) with objects, reference to remote objects or simple data. This is called
binding. The set of bindings is called the context. Applications use the JNDI interface to access resources.
To put it very simply, it is like a hashmap with a String key and Object values representing resources on the web.
What Issues Does JNDI Solve
Without JNDI, the location or access information of remote resources would have to be hard-coded in applications or made available in a configuration. Maintaining this information is quite tedious and error prone.
If a resources has been relocated on another server, with another IP address, for example, all applications using this resource would have to be updated with this new information. With JNDI, this is not necessary. Only the corresponding resource binding has to be updated. Applications can still access it with its name and the relocation is transparent.
I am just curious why the official docs are so ignored which elaborate the details meticulously already.
But if you'd like to understand the cases, please refer to duffymo's answer.
The Java Naming and Directory InterfaceTM (JNDI) is an application programming interface (API) that provides naming and directory functionality to applications written using the JavaTM programming language. It is defined to be independent of any specific directory service implementation. Thus a variety of directories--new, emerging, and already deployed--can be accessed in a common way.
And its architecture
And normally how you use it.
The Java Naming and Directory InterfaceTM (JNDI) is an application programming interface (API) that provides naming and directory functionality to applications written using the JavaTM programming language. It is defined to be independent of any specific directory service implementation. Thus a variety of directories--new, emerging, and already deployed--can be accessed in a common way.
While JNDI plays less of a role in lightweight, containerized Java applications such as Spring Boot, there are other uses. Three Java technologies that still use JNDI are JDBC, EJB, and JMS. All have a wide array of uses across Java enterprise applications.
For example, a separate DevOps team may manage environment variables such as username and password for a sensitive database connection in all environments. A JNDI resource can be created in the web application container, with JNDI used as a layer of consistent abstraction that works in all environments.
This setup allows developers to create and control a local definition for development purposes while connecting to sensitive resources in a production environment through the same JNDI name.
reference :
https://docs.oracle.com/javase/tutorial/jndi/overview/index.html
I'm thinking about possible alternatives for our EJB based service layer and wondered if it would make sense to use just the service and database layer of Grails together with the Remoting Plugin or is this using a sledgehammer to crack a nut?
Speaking of the Remoting Plugin: is there a standard way of generating a JAR file, that contains the necessary classes to make a remote call to a Grails service from a non-Spring Java application?
Interesting idea. I don't think it'd be overkill at all. The nice thing is that your service would be very portable across protocols and deployment options (e.g. put a controller layer on top and it's instantly embedded). This gives you the benefits of EJB's (persistence) + the ability to use Groovy and GORM.
FWIW, we're using Grails as our service tier; in come cases we use it embedded (as a plugin), in others we expose the services (via controllers) as JSON or SOAP; I see exposing as RMI as a variation of what we're doing (without the controller layer).
I have two separate installs of WebSphere. (Actually one is WebSphere Application Server V6.1 with EJB 3.0 and Web Services feature packs, and the other server is WebSphere ESB Server V6.2). However, I know that ESB is really built on top of WAS, so it has all the configuration settings that a regualr WAS server has.
In my ESB server, I am trying to expose a service written as EJB 3.0 that will be deployed to the WAS 6.1 server. My question is not how to get EJB 2.1 calls to call into an EJB 3.0. We've done that already. My question is how to call across physical VM's. The WebSphere Application Server is running in its own cell/node/server from the ESB Server. From what I've read in IBM documentation, it is possible to set up a namespace binding on WAS to point to a remote EJB on another WAS instance. Thus you could use JNDI to lookup a bean on one WAS instance that really resides in another WAS instance. The beauty of this method is the location of the EJB you want is abstracted to the container level, and you don't have to drag around properties files of the IP addresses and ports that you need to access the bean should it change servers, etc. You just make a standard JNDI lookup to a remote EJB and you get it.
Sounds like it can be done. (See the following links:
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tnam_view_bindings.html) Especially follow the links on EJB and Indirect namespace bindings.
But I've been hitting my head against this for a while. It makes sense. It looks like it can be done. And the Indirect namespace binding looks the most promising. But I can't get it to work quite right. My ESB server keeps complaining about not finding comp/env/ejb in the context in which I am asking for it. Very puzzled by this one.
Just wondering if anybody has done this kind of thing before. Can you give me a concrete example of how you set this up in WAS to do so? Any help is appreciated
Well, I have since talked with IBM on how to do this and was surprised by their answer. They answered that if you are talking EJB to EJB within the same server or server cluster, then use EJB RMI via IIOP. With JNDI this abstracts where the bean is actually running (in a clustered environment).
If you are going from one server (or server cluster) across into a different server (or server cluster) regardless of whether or not the target and source are in the same cell, IBM recommended that you use messaging or web services. They felt that was a better method of abstraction between applications to keep them from being "tied" to each other. They did say that you could get EJB's to talk RMI via CORBA, but said to do that ONLY if absolutely necessary. And of course, you would need to know the IP and port number for coming in over CORBA (and that times each cluster member if in a clustered environment).
Again, this kind of surprised me, but it does make sense. Just thought I'd share these thoughts with the world, especially if you are working with WebSphere.
how to lookup from tomcat
use IBM JDK as runtime for tomcat
find bootstab port , use iiop in PROVIDER_URL
I was stuck with the same problem. After trying to include all the websphere and ibm orb jars found this article at ibm
How to lookup an EJB and other Resources in WebSphere Application Server using a Oracle JDK client - http://www-01.ibm.com/support/docview.wss?uid=swg21382740
basically used the CNCtxFactory instead of WsnInitialContextFactory
//props.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
env.put("java.naming.provider.url", iioppath);