Support Questions
Find answers, ask questions, and share your expertise

apache livy and ajax post requests: Method Not Allowed

Good morning everyone,

can someone help me to see why this jquery code can note create a session to the apache livy? I got these errors :

OPTIONS http://localhost:8998/ 405 (Method Not Allowed) and Failed to load http://localhost:8998/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8084' is therefore not allowed access. The response had HTTP status code 405.

This is the code I used :

$.ajax({
            type: 'POST',
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            url: 'http://localhost:8998',
            data: {kind: 'spark'},
            success: function (resultat) {
                document.getElementById(response).innerHTML = resultat;
                console.log(resultat);
            }
        });

Thank you for your help

1 ACCEPTED SOLUTION

Accepted Solutions

@Melchicédec NDUWAYO

I tried deleting one comment and ended up deleting full thing, sorry. I have a backup of the instructions I provided initially. Later we found this was related to CORS and that Livy does not support it yet. So alternatives are using an http proxy or your web application to redirect the requests.

web page --> your web app backend --> livy

I recommend you use google Postman as it has a feature to generate jquery code.

Here is the jquery code to start a session:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://localhost:8999/sessions",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json",
    "X-Requested-By": "user",
    "Cache-Control": "no-cache",
  },
  "processData": false,
  "data": "{\"kind\": \"spark\"}"
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

Of course on the done function instead of printing to console you need to parse the json and grab the session id to use later as a variable. Then you will need to wait until session state transitions to idle, in oder to do this you need to execute the following request in regular intervals until state = idle:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://c24-node2:8999/sessions/<session_id>",
  "method": "GET",
  "headers": {
    "Cache-Control": "no-cache",
    "Postman-Token": "60246911-890b-4f81-8635-da52e54ef633"
  }
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

Above done function needs to parse the json and check if state is idle Once state is idle we can submit code using the following jquery code:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://c24-node2:8999/sessions/<session_id>/statements",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json",
    "X-Requested-By": "user",
    "Cache-Control": "no-cache",
    "Postman-Token": "aece2722-cbdd-48a2-ae9a-821aba97a2b6"
  },
  "processData": false,
  "data": "{\"code\": \"1 + 1\"}"
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

The above is pushing code "1+1" - Same as before with session we need to grab the result in done function and save the statement id to use later to retrieve the results. With session id and statement id we can retrieve the results of the execution by running the following jquery:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://c24-node2:8999/sessions/<session_id>/statements/<statment_id>",
  "method": "GET",
  "headers": {
    "Content-Type": "application/json",
    "X-Requested-By": "user",
    "Cache-Control": "no-cache",
    "Postman-Token": "3be8a12e-af07-4567-83ff-e37b48974e76"
  }
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

The result of the above execution should be similar to this:

{
    "id": 1,
    "code": "1 + 1",
    "state": "available",
    "output": {
        "status": "ok",
        "execution_count": 1,
        "data": {
            "text/plain": "res1: Int = 2"
        }
    },
    "progress": 1
}

Hopefully this will help you. Feel free to update this thread if you have any questions. HTH *** If you found this answer addressed your question, please take a moment to login and click the "accept" link on the answer.

View solution in original post

11 REPLIES 11

Hi @Felix Albani . Thank you for your help. I tried your first code, for starting a session, but I still get the error : OPTIONS http://localhost:8998/sessions 405 (Method Not Allowed). Do you know why this? Thank you again for your efforts.

Hi @Felix Albani , thank you again for your help.

I think, based on this : https://issues.apache.org/jira/browse/LIVY-444?jql=text%20~%20%22LIVY%3A%20CORS%22, my problem is because Livy REST API does not have routes to handle OPTIONS requests. I have a web application and apache livy which are using different ports, so then different domains. Do you think it is possible to run apache Livy REST API into my existing java web application so that they can have the same port and then the same domain? Do you have any idea?

Thank you

Hi @Felix Albani , can you help please, by telling me where I can put that configuration that he is talking here: https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-respo...? I still have the problem and I think that problem is because apache livy doesn't allow CORS. I don't know exactly where I can tell apache livy to accept this. Which kind of server does apache livy use? It uses apache, right? So I tried to modify /etc/apache2/apache2.conf in my Ubuntu system but it doesn't work. I really need a help!

Thank you and I hope you understand well my English which must be very bad.

Hi every one,

do you think it is possible to enable cors in apache livy? I think my problem is from that. I tried all propositions from forums but no solution can resolve my problem. May be it is possible by modifying the livy.conf or livy-client.conf files to do that. But I don't know how.

Thank you

Hi @Felix Albani ,

is this normal that I can not see any of your comments on this topic? That was helping me in resolving my problem. Please, I know I didn't give a return because I was searching in my side how to make proxy reverse.

Is that possible to put again your comments here?

Thank you very much for your help.

@Melchicédec NDUWAYO

I tried deleting one comment and ended up deleting full thing, sorry. I have a backup of the instructions I provided initially. Later we found this was related to CORS and that Livy does not support it yet. So alternatives are using an http proxy or your web application to redirect the requests.

web page --> your web app backend --> livy

I recommend you use google Postman as it has a feature to generate jquery code.

Here is the jquery code to start a session:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://localhost:8999/sessions",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json",
    "X-Requested-By": "user",
    "Cache-Control": "no-cache",
  },
  "processData": false,
  "data": "{\"kind\": \"spark\"}"
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

Of course on the done function instead of printing to console you need to parse the json and grab the session id to use later as a variable. Then you will need to wait until session state transitions to idle, in oder to do this you need to execute the following request in regular intervals until state = idle:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://c24-node2:8999/sessions/<session_id>",
  "method": "GET",
  "headers": {
    "Cache-Control": "no-cache",
    "Postman-Token": "60246911-890b-4f81-8635-da52e54ef633"
  }
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

Above done function needs to parse the json and check if state is idle Once state is idle we can submit code using the following jquery code:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://c24-node2:8999/sessions/<session_id>/statements",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json",
    "X-Requested-By": "user",
    "Cache-Control": "no-cache",
    "Postman-Token": "aece2722-cbdd-48a2-ae9a-821aba97a2b6"
  },
  "processData": false,
  "data": "{\"code\": \"1 + 1\"}"
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

The above is pushing code "1+1" - Same as before with session we need to grab the result in done function and save the statement id to use later to retrieve the results. With session id and statement id we can retrieve the results of the execution by running the following jquery:

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://c24-node2:8999/sessions/<session_id>/statements/<statment_id>",
  "method": "GET",
  "headers": {
    "Content-Type": "application/json",
    "X-Requested-By": "user",
    "Cache-Control": "no-cache",
    "Postman-Token": "3be8a12e-af07-4567-83ff-e37b48974e76"
  }
}
 
$.ajax(settings).done(function (response) {
  console.log(response);
});

The result of the above execution should be similar to this:

{
    "id": 1,
    "code": "1 + 1",
    "state": "available",
    "output": {
        "status": "ok",
        "execution_count": 1,
        "data": {
            "text/plain": "res1: Int = 2"
        }
    },
    "progress": 1
}

Hopefully this will help you. Feel free to update this thread if you have any questions. HTH *** If you found this answer addressed your question, please take a moment to login and click the "accept" link on the answer.

View solution in original post

Hi. Thank you very much. That helps me.

Hi @Felix Albani, I come back again for your help.

I am trying to execute your code step by step, but at the end in the result I get "output": null. Do you know where the problem can come from?

And the state: waiting in the result.

But in the livy/ui I see the result correctly.

Maybe I have to wait until state: available? No?

Here is what I get exactly:

{id: 0, code: "1 + 1", state: "waiting", output: null, progress: 0}code:"1 + 1"id:0output:nullprogress:0state:"waiting"__proto__:constructor:ƒ Object()hasOwnProperty:ƒ hasOwnProperty()isPrototypeOf:ƒ isPrototypeOf()propertyIsEnumerable:ƒ propertyIsEnumerable()toLocaleString:ƒ toLocaleString()toString:ƒ toString()valueOf:ƒ valueOf()__defineGetter__:ƒ __defineGetter__()__defineSetter__:ƒ __defineSetter__()__lookupGetter__:ƒ __lookupGetter__()__lookupSetter__:ƒ __lookupSetter__()get __proto__:ƒ __proto__()set __proto__:ƒ __proto__()

Thank you!

Hi @Felix Albani, thank for your help in this topic. It really helped me. Now I am trying to submit a code from a textarea,

I succeded to send a simple code of operations, for example 5+7, 8-7,789/0, 47*7. The problem is when the user wants to submit a huge code with many strings, how can we get that automatically and send it to the apache livy server? In other words, how can I change this line : "data":"{\"code\": \"1 + 1\"}"?

This is what I did "data": "{\"code\": \""+code+"\"}", but i works only for operations!

Thank you very much!