How to make a xml-RPC call from OpenERP to a JavaServer? - java

I am new to OpenERP and playing around.
My plan is to connect OpenERP to a SOAP Webservice. Hence, OpenERP does only support XML-RPC I will write a converter in Java. I am able to make a call from Java to OpenERP but I do not know how I should start with the other direction.
My goal is to change the Manufacturing Workflow. After "Confirm Production" it should send some data via XML-RPC to my Java xmlrpc Server.
I created a new node and add a Server Action with the following code:
import xmlrpclib
sock = xmlrpclib.ServerProxy('http://localhost:8080/xmlrpctest/xmlrpc')
This gives me the error
NameError: name 'xmlrpclib' is not defined
I thought the xmlrpclib is always included in OpenERP.
I would be glad if somebody could tell what the right approach is to call from OpenERP over XML-RPC a java server.
Thanks in advance.

As Andrei says, this isn't an OpenERP question, this is just a general python question. You will need to look at the python SOAP libraries to make SOAP calls to your java web-service.
As a caution though, think carefully about hooking the SOAP call into the workflow as you will get all your transactions failing in OpenERP if the java server is down. Unless you need them to be synchronous would be better to use a queue (Celery, Rabbit etc) and just dump the message into the queue. You can use the OpenERP scheduled tasks to kick of a synchronise process when you need.

Don't do it in a server action. You can read in the OpenERP documentation (the link I already sent you :)) the following
The code is executed using the exec function of python, which is run in the dictionary namespace with variables: object,time,cr,uid,ids
Well, I think that's not completely true - actions in OpenERP are executed trough the tools.safe_eval.safe_eval() method. From the doc string of this method:
"""safe_eval(expression[, globals[, locals[, mode[, nocopy]]]]) -> result
System-restricted Python expression evaluation
Evaluates a string that contains an expression that mostly
uses Python constants, arithmetic expressions and the
objects directly provided in context.
This can be used to e.g. evaluate
an OpenERP domain expression from an untrusted source.
Throws TypeError, SyntaxError or ValueError (not allowed) accordingly.
Without entering in the details, it's a restricted execution. Instead of this do the following:
Create your own module
Create a class which inherits from mrp.production. I mean, do
_inherit = 'mrp.production'
inside your class.
Override in this class the method executed after "Confirm Production" (whatever this is).
Do what you need with your rpc server in this new method.
Don't forget to call super()

'xmlrpclib' was introduced into the Python standard library at Python 2.2, and in version 3.0 was renamed to 'xmlrpc' and reorganised.

Related

How i can receive variable from another thread in Jmeter

in the first thread, I received JSON (format - {"id":6054,"name":"Jmeter created chat","description":"jmeter created test"})
I want to use it in the second thread variable '6054'
I use BeanShell Assertion with code:
${__setProperty(("id":"(.+?)"), ${chat_id)};
but it, of course, doesn't work, please tell me the right way..
many thanks
It won't work because your __setProperty() function call doesn't make sense at all and it's syntactically incorrect
Since JMeter 3.1 you're supposed to use JSR223 Test Elements and Groovy language for scripting
So
Remove your Beanshell Assertion
Add JSR223 PostProcessor as a child of the request which returns the above response
Put the following code into "Script" area:
props.put('chat_id', new groovy.json.JsonSlurper().parse(prev.getResponseData()).id as String)
In 2nd Thread Group access the value using __P() function as:
${__P(chat_id,)}
Demo:
More information regarding what these prev and props guys mean can be found in the Top 8 JMeter Java Classes You Should Be Using with Groovy article
P.S. You may find Inter-Thread Communication Plugin easier to use

Consume an "asp service" with Java (without WSDL)

I'm not sure about the exact denomination, but I have an "web asp service" (from a .NET application) who gives me a XML file. (There is no WSDL...)
For exemple, I can question the web service with an URL like that :
http://Connectiquetest:86/Vaudoise/srv_db/db2_personnes.asp?Nopers=529720&SearchMode=1&Name=Smith
Where Nopers=52920, SearchMode=1 and Name=Smith are used to return to me the response I want. (The URL is for an internal system, you cannot access to it without a VPN)
The content type return is : "text/xml" (it's a classic well-formed XML).
So, how can I use this informations to make a call from a Java application to receive the XML ? Anybody can tell me what is it exactly (maybe a specific implementation of SOAP ?)
Thanks !
The most simple (and yet most labor intensive) approach would be to open an HttpURLConnection. You can do that by calling URL.openConnection(). The URL object would obviously be based on the URL you mentioned, optionally appending the parameters Nopers, SearchMode and Name. You could then call getInputStream() to access the response of the call. Next would be parsing the XML to interpret the result.
However, as said, this requires a lot of low-level code (especially when reading the input, parsing the XML, and so on). Consider using something like Apache HttpComponents for HTTP-related work, combined with something like JAXB for easily converting the retrieved XML to plain old Java objects.
Using JAXB might require you to have an XML schema. In the ideal situation, it already exists (written by the people who wrote the ASP service). In the sub-ideal situation, you'll have to derive it yourself.

How am I supposed to use Apache XML-RPC's TypeConvertorFactory on the server side?

I am struggling to get Apache XML-RPC to call my TypeConvertorFactory at all. It is calling it on the client side (only return values confirmed to work so far, haven't tested parameters) but the server side isn't calling it at all.
My initialisation code looks like this:
XmlRpcServlet servlet = new XmlRpcServlet();
XmlRpcServerConfigImpl config = new XmlRpcServerConfigImpl();
config.setEnabledForExtensions(true);
servlet.getXmlRpcServletServer().setConfig(config);
servlet.getXmlRpcServletServer().setTypeConverterFactory(
new ServerTypeConvertorFactory());
The API looks like this:
private interface API {
AvailableLicencesResponse availableLicences();
}
AvailableLicencesResponse is just an ordinary boring, albeit deeply nested JavaBean.
At the moment, the server sends this response as Base64 (this works because I called setEnabledForExtensions(true) - but if I don't call that, I get "unexpected end of stream" type errors instead, with no additional error anywhere to tell me why.)
I have set breakpoints inside ServerTypeConvertorFactory and it seems that none of the methods are being called on the server. The same breakpoints show the client calling convert() when the server hands back the result, but the result is already the correct type due to serialisation magic so I don't need to convert it.
Essentially, what I am trying to do is to implement a wire protocol which conforms to standard XML-RPC (and doesn't use huge amounts of Base64 data...) while still having an API which doesn't require a thousand casts and calls to Map.get(). I also want to avoid having to make more calls than necessary, which is why I'm returning a bean instead of having separate methods to get each property of it, which would have worked too.
(Also, if there is a simpler to use API than this one, I'm open for suggestions. It started out being really easy, but that's until you need to customise it. Also, anyone suggesting Axis or other SOAP-based APIs will be shot at dawn.)

Ideal web service protocol for single-operation Java program with many parameters?

I have been tasked with making an existing Java program available via a web service that will be invoked through a PHP form.
The program performs biological simulations and takes a large number of input parameters (around 30 different double, double[], and String fields). These parameters are usually setup as instance variables for an "Input" class which is passed into the the program, which in turn produces an "Output" class (which itself has many important fields). For example, this is how they usually call the program:
Input in = new Input();
in.a = 3.14;
in.b = 42;
in.c = 2.71;
Output out = (new Program()).run(in);
I am looking for a way to turn this into a web service in the easiest way possible. Ideally, I would want it to work like this:
1) The PHP client form formats an array containing the input data and sends it to the service.
2) The Java web service automatically parses this data and uses it to populate an Input instance.
3) The web service invokes the program and produces an Output instance, which is is formatted and sent back to the client.
4) The client retrieves the input formatted as an associative array.
I have already tried a few different methods (such as a SOAP operation and wrapping the data in XML), but nothing seems as elegant as I would like. The problem is that the program's Input variable specifications are likely to change, and I would prefer the only maintenance for such changes to be on the PHP form end.
Unfortunately, I don't have enough experience with web services to make an educated decision on what my setup should be like. Does anyone have any advice for what the most effective solution would be?
IMHO JSON RESFULL will be the best. Look here http://db.tmtec.biz/blogs/index.php/json-restful-web-service-in-java
If your program is stand alone java use jetty as an embedded web server.
If the application is already running as a web application skip this.
The second phase is creating web service. I'd recommend you restful web service. It is easier to implement and maintain than SOAP. You can use XML or JSON format for data. I'd probably recommend you JSON.
Now it is up to you. If you already use some kind of web framework, check whether it supports REST. If you do not use any framework you can implement some kind of REST API using simple servlet that implements doPost(), parses input (JSON) and calls implementation.
There are a lot of possibilities. You should search for data serialization formats and choose the most suitable for this purpose.
One possibility would be to use Protocol Buffers.

Which options do I have for Java process communication?

We have a place in a code of such form:
void processParam(Object param)
{
wrapperForComplexNativeObject result = jniCallWhichMayCrash(param);
processResult(result);
}
processParam - method which is called with many different arguments.
jniCallWhichMayCrash - a native method which is intended to do some complex processing of it's parameter and to create some complex object. It can crash in some cases.
wrapperForComplexNativeObject - wrapper type generated by SWIG
processResult - a method written in pure Java which processes it's parameter by creation of several kinds (by the kinds I'm not meaning classes, maybe some like hierarchies) of objects:
1 - Some non-unique objects which are referencing each other (from the same hierarchy), these objects can have duplicates created from the invocations of processParam() method with different parameter values. Since it's costly to keep all the duplicates it's necessary to cache them.
2 - Some unique objects which are referencing each other (from the same hierarchy) and some of the objects of 1st kind.
After processParam is executed for each of the arguments from some set the data created in processResult will be processed together. The problem is in fact that jniCallWhichMayCrash method may crash the entire JVM and this will be very bad. The reason of crash may be such that it can happen for one argument value and not for the other. We've decided that it's better to ignore crashes inside of JVM and just skip some chunks of data when such crashes occur. In order to do this we should run processParam function inside of separate process and pass the result somehow (HOW? HOW?! This is a question) to the main process and in case of any crashes we will only lose some part of data (It's ok) without lose of everything else. So for now the main problem is implementation of transport between different processes. Which options do I have? I can think about serialization and transmitting of binary data by the streams, but serialization may be not very fast due to object complexity. Maybe I have some other options of implementing this?
Let us assume that the processes are on the same machine. Your options include:
Use a Process.exec() to launch a new process for each request, passing the parameter object as a command line argument or via the processes standard input and reading the result from thr processes standard output. The process exits on completion of a single request.
Use a Process.exec() to launch a long running process, using the Processes standard input / output for sending the requests and replies. The process instance handles multiple requests.
Use a "named pipe" to send requests / replies to an existing local (or possibly remote) process.
Use raw TCP/IP Sockets or Unix Domain Sockets to send requests / replies to an existing local (or possibly remote) process.
For each of the above, you will need to design your own request formats and deal with parameter / result encoding and decoding on both sides.
Implement the process as a web service and use JSON or XML (or something else) to encode the parameters and results. Depending on your chosen encoding scheme, there will be existing libraries deal with encoding / decoding and (possibly) mapping to Java types.
SOAP / WSDL - with these, you typically design the application protocol at a higher level of abstraction, and the framework libraries take care of encoding / decoding, dispatching requests and so on.
CORBA or an equivalent like ICE. These options are like SOAP / WSDL, but using more efficient wire representations, etc.
Message queuing systems like MQ-series.
Note that the last four are normally used in systems where the client and server are on separate machines, but they work just as well (and maybe faster) when client and server are colocated.
I should perhaps add that an alternative approach is to get rid of the problematic JNI code. Either replace it with pure Java code, or run it as an external command or service without a Java wrapper around it.
Have you though about using web-inspired methods ? in your case, typically, web-services could/would be a solution in all its diversity :
REST invocation
WSDL and all the heavy-weight mechanism
Even XML-RPC over http, like the one used by Spring remoting or JSPF net export could inspire you
If you can isolate the responsibilities of the process, ie P1 is a producer of data and P2 is a consumer, the most robust answer is to use a file to communicate your data. There is overhead (read CPU cycles) involved in serailization/deserialization however your process(es) will not crash and it is very easy to debug/synchronize.

Categories

Resources