Oracle connection timeout inside a Azure Function that cancels at 5mins

Viewed 45

I have the following lines of code inside a Java function:

    try{

        context.getLogger().info("Paso001");
        Class.forName("oracle.jdbc.driver.OracleDriver"); 

        context.getLogger().info("Paso002");
        Connection conn = DriverManager.getConnection(
        params.get().getConnection(), params.get().getUser(), params.get().getPassword());

        if (conn != null) {
            context.getLogger().info("Connected to the database!");
        } else {
            context.getLogger().log(Level.SEVERE, "No connection to the database!");
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR).body("Error").build();
        } 
        
        context.getLogger().info("Paso003");
        PreparedStatement sentencia = conn.prepareStatement(params.get().getSentence());
        int index = 0;
        for (Param param : params.get().getParams()) {
            index++;
            if (param.getType().equals("String")) {
                sentencia.setString(index, param.getValue());
            } else {
                sentencia.setInt(index, Integer.parseInt(param.getValue()));
            }
        }
        ResultSet rs=sentencia.executeQuery();

        JSONArray result = JsonHelper.recordList2Json(rs);

        context.getLogger().info(result.toString());
        return request.createResponseBuilder(HttpStatus.OK).body(result.toString()).build();                
    } catch(Exception e)
    { 
        context.getLogger().info("Paso00-err");
        context.getLogger().log(Level.SEVERE, e.toString());
    }

Loging only shows "Paso001" and "Paso002" but connection fails at 300000 ms (5 minutes) because no "Paso00-err" is shown in the logs. I assume that Azure Function is reaching maximum time.

Azure Function is inside a VNET integration and DATABASE is inside another local NET behind an ExpressRoute. I have assumed that Firewall is correct because opening socket to Host:Port inside the funcion seems ok:

  InetAddress IPv4 = null;
  try {
      IPv4 = InetAddress.getByName(connect.get().getHost());
  } catch (UnknownHostException e) {
      result = e.toString();
      e.printStackTrace();
      return request.createResponseBuilder(HttpStatus.OK).body(result.toString()).build();
  }


  try {
      Socket s = new Socket(IPv4, Integer.parseInt(connect.get().getPort()));
      result = "Server is listening on port " + connect.get().getPort()+ " of " + connect.get().getHost();
      context.getLogger().info(result);
      s.close();
  }
      catch (IOException ex) {
      // The remote host is not listening on this port
      result = "Server is not listening on port " + connect.get().getPort()+ " of " + connect.get().getHost();
      context.getLogger().info(result);
  }

Result gets: "Server is listening on port port of host host

Note. I get same error pointing to a public database installed locally.

Is there anything else missing to open? Any ideas?

Edit: I have rewritten code with .NET CORE 3.11...

        using (OracleCommand cmd = con.CreateCommand())
        {
            try
            {
                log.LogInformation("step001");
                con.Open();
                log.LogInformation("step002");
                cmd.BindByName = true;
                cmd.CommandText = sentence;
                OracleDataReader reader = cmd.ExecuteReader();
                log.LogInformation("step003");
                return new OkObjectResult(reader2Json(reader));
            }
            catch (Exception ex)
            {
                return new OkObjectResult("Error: "+ex.ToString());
            }
        }

and similar results but this time exception is going thrown:

Error: Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out
   at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria)
   at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
   at Oracli2.Function1.Run(HttpRequest req, ILogger log) in C:\proy\vscode\dot2\Oracli2\Oracli2\Function1.cs:line 50
1 Answers

You can increase the function time out in the hosts.json file, just so you are aware of that, but I dont think increasing it will fix your issue, 5 minutes is a generous time, unless the query you are running here does in-fact take longer than 5 minutes to return!

Can you set the retry_count & retry_delay for your connection string something small (eg: 3 tries) so you know that the time out is not because of trying to do 100 retries and not see the actual underlying error

Other issues could be to do with connectivity, best bet would be to go into the Kudu Console for the console app, open up SSH and via SSH see if you can connect to your oracle db and run a test query from here, if it's all working from here then connectivity is not the issue.

enter image description here

enter image description here

Related