Call custom-domain REST-Enabled SQL Service from APEX Developer Service - oracle

My production app is an APEX application already running in a custom domain (mydomain.com). I've already configured REST-enabled SQL Service, and connected to it successfully from another APEX installation on anther custom domain of mine. So that seems fine.
Now, I've spun up a new APEX Developer Service environment on oraclecloud, and I'm trying to create a REST-enabled SQL Service reference to point to the mydomain.com instance. I'm getting the typical error that says the endpoint does not point to a REST-enabled SQL Service.
In the past, when I've had this problem, I solved it by:
Creating an ACL for the remote domain, which allows responses to come back into the requester, and
Modifying the wallet on the requester to include the root CA certificate of the remote domain. This is needed because my custom remote instance is running HTTPS.
As far as I know, both of those require database and/or filesystem access, which I don't have in the APEX Developer Service environment on oraclecloud.
So, my question is: is it possible to do this and, if so, how?

you might execute the following in SQL Commands in order to test networking connectivity between the APEX service and your APEX instance within (yourdomain.com).
declare
l_result clob;
begin
l_result := apex_web_service.make_rest_request(
p_url => 'http://server.yourdomain.com/path/to/restenabledsql/_/sql',
p_http_method => 'GET' );
htp.p( 'Status: ' || apex_web_service.g_status_code );
end;
As this block does not pass credentials, it will never work correctly. However, based on the thrown error message, we will hopefully get a better indication about the actual cause.

Related

ORA-20000: AOP Server can not be found

I installed AOP and have now a little problem. I get the error
ORA-20000: AOP Server can not be found. Check if it is running at http://api.apexofficeprint.com/
when trying to create a template or report.
Oracle Database 18 XE
Apex 20.1
Apex Office Print 20.2
That's a general error you are receiving. This is more of a network issue than AOP.
The first step would be to check if you ACL has been set up properly. You could check this by executing the following through SQL Workshop -> SQL Commands:
select apex_web_service.make_rest_request('http://api.apexofficeprint.com/marco', 'GET') from dual;
if the ACL was configured properly you should get a "polo" string back.
If this does result in an error, you should be able to get the exact HTTP error by executing the following command:
select utl_http.get_detailed_sqlerrm from dual;
You should see something like this:
ORA-29273: HTTP request failed
ORA-06512: at "SYS.UTL_HTTP", line 1577
ORA-24247: network access denied by access control list (ACL)
The code to configure ACL can be found on oracle documentation for 20.1
I've pasted the code below to make it easier. You will need to connect to the database where Oracle Application Express is installed as SYS specifying the SYSDBA role.
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => 'api.apexofficeprint.com',
ace => xs$ace_type(privilege_list => xs$name_list('connect'),
principal_name => 'APEX_200100',
principal_type => xs_acl.ptype_db));
END;
/
For completeness I am also hyperlinking it here for other versions of APEX.
: APEX 5.0, APEX 5.1, APEX 18.1, APEX 18.2, APEX 19.1, APEX 19.2
Once this has been setup, you should be able to connect to api.apexofficeprint.com without issues. However please note that you are currently using http protocol which is unsecure and we recommend you to use https.
In order for you to use https, you will have to add the root certificate of AOP server. This blog capture the method in detail.
Furthermore if you have installed the AOP sample application, you can debug connection issues from connection test page (Debugging -> Test Connection). This page will detect the URL you have used for the plugin and allow you to check the connection. This detects ACL, wallet issues, certificate validation issue and if the server is running in the provided URL.
PS: Could it be that you used other email than support#apexofficeprint.com to contact us? I see that one of your email and the feedback were both answered within an hour.

Jdbc connection error from Google Apps Script

I have created a Google Cloud Project MySQL database to use in conjunction with the Jdbc service provided by Google Apps Script. Everything went as planned with the connection. I am basically connecting as it does in the docs.
var conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
I shared the file with another account and all of a sudden I am seeing a red error saying:
'Failed to establish a database connection. Check connection string, username and password.'
Nothing changed in the code, but there is an error. When I go back to my original account and run the same bit of code, there is no error. What is happening here? Any ideas?
Jdbc.getConnection works from both: my account and another account:
var conn = Jdbc.getConnection('jdbc:mysql://' + IP + ':3306/' + database_name, user, password)
I'm really confused because the recommended method did not work.
There are two ways of establishing a connection with a Google Cloud
SQL database using Apps Script's JDBC service:
(Recommended) Connecting using Jdbc.getCloudSqlConnection(url)
Connecting using Jdbc.getConnection(url)
Notes:
IP is a Public IP address from the OVERVIEW tab in your database console:
I've allowed any host when created a user:
I am not sure whether this question has been resolved or not, but let me add this answer.
I also faced the same problem but I found the resolution. What I did is:
First, go to the console.
https://console.cloud.google.com
Then, open IAM.
and add the account as a member and add this permission: "Cloud SQL Client".
I think this is a permission issue in your second account. Necessary information are missing in your question. But, the secound account, if run as a another user, won't necessarily have your sqlservice authorization. The permission,
https://www.googleapis.com/auth/sqlservice
Manage the data in your Google SQL Service instances
is required to use Jdbc.getCloudSqlConnection(url), while Jdbc#getConnectionUrl() just requires external link connection permission
https://www.googleapis.com/auth/script.external_request
I believe that you can only connect to sql instances owned by you with getCloudSqlConnection() which doesn't even require external connection permission. This method probably calls your sql instance internally.
References:
Jdbc#getCloudConnection
Jdbc#getConnection
Conclusion
To connect to any external service, you need external_request permission. But, You don't need that permission to connect to your own documents say, Spreadsheets owned by you/have edit access permission - through SpreadsheetApp.openByUrl(). I believe it's the same thing with Jdbc.getCloudSqlConnection(). It calls your Google sql internally - So, even if you grant external request permission, It won't work. What will work for this method is
Installable triggers (which runs as you).
Add the second account also as owner in GCP-IAM (may not work though) See this answer
I'd double-check once again all IP ranges which should be whitelisted. According to your description it worked fine in first account, probably in second account Apps Script uses another IP for connection, which was not whitelisted or whitelisted with some typo. Could you share screenshot how did you exactly whitelist the ranges from this article?
I have a GAS Add-On that uses a Google cloud dB. I initially set this up by:
Whitelisting Google Cloud IP ranges in my SQL instance
Getting the script.external_request scope approved for OAuth Consent screen
This all works great from GAS for the add-on, but I suspect that if this whitelist is not comprehensive and volatile (which I expect it is), I will see intermittent connectivity issues.
I recently added a Firebase web app that needs access to the same dB. I had issues, because Firebase does not conform to those Google IP ranges and does not expose its IP for whitelisting. So I had to create a socket layer connection as if Firebase was an external service.
Which got me thinking, should I put a socket layer in my GAS Add-On? But nothing in the GAS JBDC Class documentation indicates a socket parameter.
Which leads me to a question that was not really answered in this thread:
Does anyone know why Jdbc.getCloudSqlConnection(url) is the "Recommended" approach? The documentation seems to imply that because the IP whitelisting is not required, Jdbc.getCloudSqlConnection(url) is using a socket (or some other secure method) to connect to the dB?
It also seems silly that if that is the case, that I would need two have two sensitive scopes to manage a dB connection. I would rather not go through another OAuth const audit and require my users to accept another scope unless there is a benefit to doing so.

UTL_HTTP Begin Request failure after Database upgrade

I am currently running into issues
ORA-29273: HTTP request failed
ORA-29259: end-of-input reached
when trying to do the begin_request method:
utl_http.set_wallet('','');
v_soap_ep = WALLET_PATH;
utl_http.begin_request(v_soap_ep, 'POST', 'HTTP/1.1');
This issue just started occurring today (Worked yesterday), and no changes to the code happened, although there was a database upgrade from 11g -> 12c. The WALLET_PATH links to a valid address, but the WALLET_PATH links to a 11g database (not 12c). I have little knowledge on this subject, and was wondering if this error was possibly caused by the two different database versions trying to work together.
Note: I put an invalid address into the c_soap_ep variable, and recieved a different error. (So that is why I am thinking there might be a compatability issue). Any thoughts or areas I can check out would be helpful, thanks.
ORA-29273: HTTP request failed
ORA-12545: Connect failed because target host or object does not exist
You can't use 11g wallets in 12c. Because, wallet creation is totally different in 12c as it uses new syntax.
For example:
-- Create
ADMINISTER KEY MANAGEMENT CREATE KEYSTORE 'keystore_location'
IDENTIFIED BY software_keystore_password;
-- Open
ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN
IDENTIFIED BY software_keystore_password;
-- Close
ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE
IDENTIFIED BY software_keystore_password;
So, try creating a new wallet/keystore in 12c then use it for utl_http

Problem with UTL_HTTP Package in Oracle APEX

I have a problem with APEX. We have two servers. One (with running Oracle APEX) is the university server, which we have only access to the workspace. The other is my Linux Computer at home, which acts as a server (running Tomcat with Jasperreports container). I want to send a UTL_HTTP request from the APEX machine to the Jasperreports machine. There is a button, which triggers a process with following code:
begin
xlib_jasperreports.set_report_url('http://X.X.X.X:8080/JasperReportsIntegration/report');
xlib_jasperreports.show_report (p_rep_name => :p5_rep_name,
p_rep_format => :p5_rep_format,
p_data_source => :p5_data_source,
p_out_filename => :p5_out_filename,
p_rep_locale => :p5_rep_locale,
p_rep_encoding => :p5_rep_encoding,
p_additional_params => :p5_additional_params);
-- stop rendering of the current APEX page
apex_application.g_unrecoverable_error := true;
end;
After 20 to 30 seconds after I pushed the triggering button I get following errormessage:
ORA-29273: HTTP request failed ORA-06512: at "SYS.UTL_HTTP", line 1029 ORA-12535: TNS:operation timed out
I checked the set_report_url function by setting a common url . And it worked. Does anyone have a clue?
Thanks in advance,
Haniball
The latter version of Oracle have Network ACL security, so it might be that the schema owner doesn't have privileges to access that particular URL. However I'd expect a security violation for that.
Another alternative is that it is being blocked by a firewall between the database server and your home machine. It is possible (likely) that the database server machine has been set up to only allow a small list of sites to be accessed (or none at all). You may also have a firewall on your home machine that prevents access from machines not on a list of IP addresses/ranges.
Try some basic UTL_HTTP actions against a variety of sites (eg the google.com home page), and see what response you get.
Missed the obvious UTL_HTTP.set_transfer_timeout. It may be that the job takes a bit too long at the home server.

Logging into oracle db as a global user

We are trying to shape up an old, 2 tier, Delphi based application. It originally uses database authentication, we'd like to transform the db user accounts to global users, so an OID server could perform the authentication instead of the database.
The Delphi program can no longer log into the database if the account is a global user. I'm trying to understand the login protocol, so far without results.
Similar thing happens with SQLDeveloper, I can't connect as a global user. SQLPlus however works with both kinds of users. We checked the information flow with Wireshark. When the dbserver asks back for a password, the SQLPlus sends it, while the SQLDeveloper doesn't send a password when attempting to connect as a global user.
The client sends the application name too in the login request. Is it possible that we have to store the client app name in the LDAP itself?
To connect to Oracle using OID, application must properly configure OCI (Oracle Call Interface). The data access components (which one ?), you are using, must set OCI_ATTR_DISTINGUISHED_NAME session attribute. If that is not done, then you will be not able to connect to Oracle server using ODI and OCI.
You should check your components documentation for this feature. And if it is not implemented, then discuss this issue with the components vendor. Actually, there is not much work to implement, but some work to setup testing environment is required ...

Resources