I am working on an application in Java on Google App Engine where we have a concept of RPC, but when should we ideally make use of RPC? The same functionality that I am doing with RPC could be implemented even without it. So in what scenario should ideally RPC be designed.....?
You typically use RPC (or similar) when you need to access a service that is external to the current application.
If you are simply trying to call a method that is part of this application (i.e. in this application's address space) then it is unnecessary ... and wasteful to use RPC.
... when should we ideally make use of RPC?
When you need it, and not when you don't need it.
The same functionality that I am doing with RPC could be implemented even without it.
If the same functionality can be implemented without RPC, then it sounds like you don't need it.
So in what scenario should ideally RPC be designed.....?
When it is needed (see above).
A more instructive answer would be scenarios where there are good reasons to implement different functions of a "system" in different programs running in different address spaces and (typically) on different machines. Good reasons might include such things as:
insulating one part of a system from another
implementing different parts of a system in different languages
interfacing with legacy systems
interfacing with subsystems provided by third party suppliers; e.g. databases
making use of computing resources of other machines
providing redundancy
and so on.
It sounds like you don't need RPC in your application.
RPC is used whenever you need to access data from resources on the server that are not available on the client. For example web services, databases, etc.
RPC is designed for request/response. i.e. you have a self contained request to a service and you expect a response (return value or a success/failure status)
You can use it anywhere you might use a method call except the object you are calling is not local to the current process.
Related
I have a Liferay instance running on a URL like example.org/app. This instance does have a REST API that would normally be running under example.org/app/o/restpath.
The way the server running this instance is that the frontend is accessible without restrictions from the outside, however the REST API is only accessible from the inside the network under a URL like example.org/rest.
I need to make sure that it is impossible to access the REST API with example.org/app. I should also be impossible to access the frontend with example.org/rest. Does anybody have any suggestions?
There are tons of ways of doing that, the best one will depend on your stack, preferences and abilities.
A reverse proxy is the first that comes to mind, bearing in mind that is is normally better if your app has control of who can access it. So a wrapper or a filter checking who is accessing would help. But even then, is the filter to be put on the main application or on your module? That is an evaluation that needs to come from you.
You can also combine the proxy strategy, with a filter, just in case one day you are tuning up your proxy and let something through. You can also decide change your proxy server too..
Or your company already have a proxy that enables traffic going out, and would be easier if that proxy was to have access...
Your servlet contained might also be able to provide such control, so you do not actually need a proxy.
Although I would feel more comfortable if that kind of feature was in the application layer itself, like a wrapper for your component and that wrapper provides the service, a filter, or even a method in in the entry-point, while the others are just extra and to reduce load.
Some companies have networks devices that go up several layers of the network stack, those have lots of potential to help here too, IDS would be able to provide alarms, triggers and such...
As it stands, one would need more information to help you more, even in what you mean by "ensure" ( how far this assurance need to go, like are you thinking about passwords, certificates, IDS, or a simple approach like the mentioned ones ), but I guess that covers it.
I was trying to find out if there is any difference when I am calling a service through its local interface / remote interface in performance within the same JVM.
Based on this article:
http://www.onjava.com/pub/a/onjava/2004/11/03/localremote.html?page=last&x-showcontent=text
Local call should be a bit faster especially in cases for Collection of Objects.
Based on my testing I could not find a big difference between the two however maybe I was trying it with small amount of data.
But anyway I would like to know if it has any downfall to call a service through its remote interface when we are in the same JVM because in my project we are generating both local/remote interfaces however there are no real remote calls, the client and the service is within the same JVM and I am thinking about cleaning up the mess and removing the unnecessary generated remote views because people started to use both without reason.
Thanks!
implementation will vary between containers how remote interfaces perform, you cannot rely on it performing similar to local interfaces (though most containers will realize you're actually accessing a 'local' remote interface). There can be differences, like spawning a new thread for the remote call, passing values by reference (you can for example turn this on in jboss for in-vm remote calls), etc
serialization is always slow, it should be avoided whenever possible
basically just don't do it, absolutely no reason to use the remote interfaces unless you plan on splitting your application into multiple EARs
Let me exaplain you the complete situation currently I am stuck with in.
We are developing very much complex application in GWT and Hibernate, we are trying to host client and server code on different servers because of client's requirement. Now, I am able to achieve so using JNDI.
Here comes the tricky part, client need to have that application on different Platform also, database would be same and methods would be the same, lets say iPhone / .Net version of our application. we don't want to generate Server code again because it's gonna be the same for all.
I have tried for WebServices wrapper on the top of my server code but because of complexity of architecture and Classes dependencies I am not able to do so. For example, Lets consider below code.
class Document {
List<User>;
List<AccessLevels>;
}
Document class have list of users, list of accesslevels and lot more list of other classes and that other classes have more lists. Some important server methods takes Class (Document or any other) as input and return some other class in output. And we shouldn't use complex architecture in WebServices.
So, I need to stick with JNDI. Now, I don't know how can I access JNDI call to any other application ???
Please suggest ways to overcome this situation. I am open for technology changes that means JNDI / WebServices or any other technology that servers me well.
Thanking You,
Regards,
I have never seen JNDI used as a mechanism for request/response inter-process communication. I don't believe that this will be a productive line of attack.
You believe that Web Services are inappropriate when the payloads are complex. I disagree, I have seen many successful projects using quite large payloads, with many nested classes. Trivial example: Customers with Orders with Order Lines with Products with ... and so on.
It is clearly desirable to keep payload sizes small, there are serialization and network costs, big objects will be more expensive. But it's by far preferable to have one big request than lot's of little one. A "busy" interface will not perform well across a network.
I suspect that the one problem you may have is that certain of the server-side classes are not pure data, they refer to classes that only make sense on the server, you don't want those classes in you client.
I this case you need to build an "adapter" layer. This is dull work, but no matter what Inter-process communication technique you use you will need to do it. You need what I refer to as Data Transfer Objects (DTOs) - these represent payloads that are understood in client, using only classes reasonable for the client, and which the server can consume and create.
Lets suppose that you use technology XXX (JNDI, Web Service, direct socket call, JMS)
Client --- sends Document DTO --XXX---> Adapter transform DTO to server's Document
and similarly in reverse. My claim is that no matter what XXX is chosen you have the same problem, you need the client to work with "cut-down" objects that reveal none of the server's implementation details.
The adapter has responsibility for creating and understanding DTOs.
I find that working with RESTful Web Services using JAX/RS is very easy once you have a set of DTOs it's the work of minutes to create Web Services.
I need to create a system oriented around Methods where providers can register for the Methods they handle and consumers can do two things (for now) - either get Metadata for a method or execute it. I'm considering creating a REST style architecture where methods are resources with unique URIs and an interface consisting of two methods - getMetadata and Execute.
I'll need to have an equivalent of #RequestMapping so that the provider that handles specific methods can be located by the central dispatcher. As a result the provider will return either Model or Metadata object.
This looks pretty similar to Spring MVC but I don't want to expose and consume my resources(methods) over the web and use http as this will incur unnecessary overhead. Instead I want to use it like a standard java API where java methods are called and java objects are transferred.
I can do that by writing my own equivalent of #RequestMapping and Dispatcher logic but I was wondering if there's a better way to do this with Spring. Any suggestions?
Thanks!
Kostadin
You are saying you want to do using REST and everything will have a unique URI but not over HTTP?? Sounds like you are looking for RMI or something similar... Chech Burlap or Hessian both of them has excellent support from spring.
There's software out there called NetKernel that might interest you. Its literature says that it is an implementation of Resource-Oriented Computing. It looks like it rigorously separates its logical computing model from the physical details. It's RESTful, defining a resource model, a limited set of verbs, and a naming scheme. Implemented in Java. Comes with HTTP and other transports built in.
It doesn't have a Java in-process transport, but you could probably write one for it pretty easily.
Hmm...if you never need to process requests from out-of-process sources, it's probably overkill for you, but maybe it will show you some useful patterns.
Currently, I only know a way of doing RPC for POJOs in Java, and is with the very complex EJB/JBoss solution.
Is there any better way of providing a similar functionality with a thiner layer (within or without a Java EE container), using RMI or something that can serialize and send full blown objects over the wire?
I'm not currently interested in HTTP/JSON serialization BTW.
EDIT: For clarification: I'm trying to replace an old EJB 2.1/JBoss 4 solution with something more easy to manage at the container level. I need to have entire control over the database(planning to use iBATIS which would allow me to use fairly complex SQL very easily), but the only things I want to keep over the wire are:
Invocation of lookup/data modification methods (automagic serialization goes here).
Transparent session control (authentication/authorization). I still have to see how to accomplish this.
Both items have to work as a whole, of course. No access should be granted to users without credentials.
Because I'm not very fond of writing webapps, I plan to build a GUI (Swing or SWT) that would only manage POJOs, do some reporting and invoke methods from the container. I want the serialization to be as easy as possible.
As is nearly always the case, Spring comes to the rescue. From the reference documentation, you will want to read Chapter 17. Remoting and web services using Spring.
There are several methods to choose from. The beauty of Spring is that all your interfaces and implementations are vanilla POJOs. The wiring into RMI or whatever is handled by Spring. You can:
Export services using RMI:
probably the simplest approach;
Use HTTP invoker: if remote access is an issue, this might be better for firewalls, etc than pure RMI; or
Use Web Services, in which case I would favour JAX-WS over JAX-RPC.
Spring has the additional benefit in that it can do the wiring for both the server and the client, easily and transparently.
Personally I would choose either (2) or (3). HTTP is network friendly. It's easy to deploy in a Web container. Jetty's long-lived connections give you the option over server push (effectively) over HTTP.
All of these methods allow complex objects to be sent across the wire but they are subtly different in this regard. You need to consider if your server and client are going to be distributed separately and whether it's an issue if you change the interface that you need to redistribute the class files. Or you can use a customized serialization solution (even XML) to avoid this. But that has issues as well.
Using a Web container will allow you to easily plug-in Spring Security, which can be a bit daunting at first just because there are so many options. Also, HttpSession can be used to provide state information between requests.
Simple RPC is exactly what RMI was built for. If you make a serializable interface, you can call methods on one app from another app.
If you only need value objects then just ensure the POJOs implement Serializable and write the objects across sockets (using ObjectOutputStream). On the receiving end read the objects using ObjectInputStream. The receiving end has to have a compatible version of the POJO (see serialVersionUID).
Hessian/Burlap 'protocol-ize this: http://hessian.caucho.com/ and http://www.caucho.com/resin-3.0/protocols/burlap.xtp
You could try XStream (http://x-stream.github.io/) over REST. Easy to apply on e pre-existing set of pojos.
Can you give some further information as to what you're trying to achieve, since you're not interested in rest/json ?