Can't connect to oracle database outside container with jdbc - oracle

I created a container for an Oracle Express database following these instructions, with the following command:
docker run -d -e ORACLE_PWD="root" --name testdb -p 5500:5500 -p 8080:8080 -p 1521:1521 container-registry.oracle.com/database/express:21.3.0-xe
What does work
I managed to access the database from within the container with this command:
docker exec -it testdb sqlplus system/root#//localhost:1521/XE
I also managed to access to access the Oracle Enterprise Manager on localhost:5500/em using these credentials:
Username: system
Password: root
Container Name: <blank>
What doesn't work
I fail to connect using IntelliJ, and therefore the underlying JDBC library. I use the following options:
For Password, I used root again, the JDBC URL is as follows:
jdbc:oracle:thin:#localhost:1521:XE
When I click on Test connection, IntelliJ tries to connect for about a minute, before showing the following error

I did a test on my MacOS
# fire up the database. Hint, use gvenzl images instead. Much faster!
docker run -d -e ORACLE_PWD="root" --name testdb -p 5500:5500 -p 8081:8080 -p 1521:1521 container-registry.oracle.com/database/express:21.3.0-xe
# I have sqlplus installed locally on my MacOS
echo 'select dummy from dual;' | sqlplus -S system/"root"#localhost/XE
D
-
X
echo 'select dummy from dual;' | sqlplus -S system/"root"#localhost:XE
ERROR:
ORA-12545: Connect failed because target host or object does not exist
SP2-0306: Invalid option.
# so, how is JDBC behaving taking the connect string as argument
java -cp .:./ojdbc8-19.6.0.0.jar OracleJDBC "jdbc:oracle:thin:#localhost:1521:XE"
X
java -cp .:./ojdbc8-19.6.0.0.jar OracleJDBC "jdbc:oracle:thin:#localhost:XE"
java.sql.SQLRecoverableException: IO Error: Invalid number format for port number
java -cp .:./ojdbc8-19.6.0.0.jar OracleJDBC "jdbc:oracle:thin:#localhost/XE"
X
Note. Port is not needed, defaults to 1521
cat OracleJDBC.java
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
public class OracleJDBC {
public static void main(String[] argv) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
System.out.println("Where is your Oracle JDBC Driver?");
e.printStackTrace();
return;
}
Connection connection = null;
String query = "select dummy from dual";
try {
connection = DriverManager.getConnection(argv[0], "system","root");
Statement stmt = connection.createStatement();
ResultSet rows = stmt.executeQuery(query);
while (rows.next()) {
System.out.println(rows.getString("dummy"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I cannot explain why you get the error. Can it be the JDBC version you are using? I have just proven, your connection should work. That said, you are not supposed to connect using the SID construct (:SID) anymore. You will hit the root-container and not where you are supposed to store your data - in a pluggable database. The express-edition comes with the default pluggable database "XEPDB1".
echo 'select name from v$pdbs;' | sqlplus -S system/"root"#localhost/XE
NAME
------------------------------
PDB$SEED
XEPDB1
This should be your connect string:
echo 'select dummy from dual;' | sqlplus -S system/"root"#localhost/XEPDB1
D
-
X
From here you create your app schema and user so you no longer will use the power-user 'system'.
Best of luck!

I worked perfectly well when I used the same configuration, but with this image instead of the official one.
Thanks to Bjarte Brandt for pointing me to this image.

Related

Got a 08003 when DB2 Calls in sourced Code

I hope this post is better to understand:
I use the bash db2 function to create a sessions and after this i want to execute some code. When i do it in a sourced Script i get a 08003.
dbconnect.sh:
#!/bin/bash
{
db2 -x +c < Connectionstring # RC is 0
db2 -x +c "Select * from Table" # RC is 4, erros say 08003
}
main.sh:
#!/bin/bash
. ./dbconnect.sh
change dbconnect to following code is not helping:
dbconnect.sh:
#!/bin/bash
db2 -x +c < Connectionstring # RC is 0
db2 -x +c "Select * from Table" # RC is 4, erros say 08003
but putting all in one file works perfekt:
#!/bin/bash
db2 -x +c < Connectionstring
db2 -x +c "Select * from Table"
Any Ideas?
The Bashversion:
4.3.48(1)-release (x86_64-suse-linux-gnx)
Linux Version:
SUSE LINUX Enterprise Server 12 SP3

airflow connection command error: unrecognized arguments

I'm upgrading to Airflow 2. From the below code in my entrypoint.sh, I had airflow connections --delete --conn_id, but I've changed it to the below according to the docs (https://airflow.apache.org/docs/apache-airflow/stable/cli-and-env-variables-ref.html)
Now I'm getting the following error for each connection:
airflow command error: unrecognized arguments: airflow_db airflow.. aws_default... azure_container_instances_default .. azure_cosmos_default
delete_default_connections() {
declare -a DEFAULT_CONNECTIONS=(
"airflow_db"
"aws_default"
"azure_container_instances_default"
"azure_cosmos_default"
)
for CONN in "${DEFAULT_CONNECTIONS[#]}" do
su -c "airflow connections delete conn_id $CONN" airflow done }
Change the command to the following, conn_id is a positional argument.
delete_default_connections() {
declare -a DEFAULT_CONNECTIONS=(
"airflow_db"
"aws_default"
"azure_container_instances_default"
"azure_cosmos_default"
)
for CONN in "${DEFAULT_CONNECTIONS[#]}" do
su -c "airflow connections delete $CONN" airflow done }

Find if a PostgreSQL database exists with bash

I have a bash function where I check if a PostgreSQL database already exists.
I capture the output. If database exist PostgreSQL returns the database name as response.
function is_database() {
local database=$1
local output=$(sudo -u postgres psql -c "SELECT datname FROM pg_catalog.pg_database WHERE datname=\"$database\";")
if [[ $output = *"${1}"* ]]
then
return 0
else
return 1
fi
}
is_database test
I get the following error:
column "test" does not exist
I am not searching for a table, but a database.
Use single quotes for string literals:
sudo -u postgres psql \
-c "SELECT datname FROM pg_catalog.pg_database WHERE datname='$database'"
Your code as it is won't work for database names like has spaces or has'quotes.

How to connect Opentracing application to a remote Jaeger collector

I am using Jaeger UI to display traces from my application. It's work fine for me if both application an Jaeger are running on same server. But I need to run my Jaeger collector on a different server. I tried out with JAEGER_ENDPOINT, JAEGER_AGENT_HOST and JAEGER_AGENT_PORT, but it failed.
I don't know, whether my values setting for these variables is wrong or not. Whether it required any configuration settings inside application code?
Can you provide me any documentation for this problem?
In server 2 , Install jaeger
$ docker run -d --name jaeger \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
In server 1, set these environment variables.
JAEGER_SAMPLER_TYPE=probabilistic
JAEGER_SAMPLER_PARAM=1
JAEGER_SAMPLER_MANAGER_HOST_PORT=(EnterServer2HostName):5778
JAEGER_REPORTER_LOG_SPANS=false
JAEGER_AGENT_HOST=(EnterServer2HostName)
JAEGER_AGENT_PORT=6831
JAEGER_REPORTER_FLUSH_INTERVAL=1000
JAEGER_REPORTER_MAX_QUEUE_SIZE=100
application-server-id=server-x
Change the tracer registration application code as below in server 1, so that it will get the configurations from the environment variables.
#Produces
#Singleton
public static io.opentracing.Tracer jaegerTracer() {
String serverInstanceId = System.getProperty("application-server-id");
if(serverInstanceId == null) {
serverInstanceId = System.getenv("application-server-id");
}
return new Configuration("ApplicationName" + (serverInstanceId!=null && !serverInstanceId.isEmpty() ? "-"+serverInstanceId : ""),
Configuration.SamplerConfiguration.fromEnv(),
Configuration.ReporterConfiguration.fromEnv())
.getTracer();
}
Hope this works!
Check this link for integrating elasticsearch as the persistence storage backend so that the traces will not remove once the Jaeger instance is stopped.
How to configure Jaeger with elasticsearch?
Specify "JAEGER_AGENT_HOST" and ensure "local_agent" is not specified in tracer config file.
Below is the working solution for Python
import os
os.environ['JAEGER_AGENT_HOST'] = "123.XXX.YYY.ZZZ" # Specify remote Jaeger-Agent here
# os.environ['JAEGER_AGENT_HOST'] = "16686" # optional, default: "16686"
from jaeger_client import Config
config = Config(
config={
'sampler': {
'type': 'const',
'param': 1,
},
# ENSURE 'local_agent' is not specified
# 'local_agent': {
# # 'reporting_host': "127.0.0.1",
# # 'reporting_port': 16686,
# },
'logging': True,
},
service_name="your-service-name-here",
)
# create tracer object here and voila!
Guidance of Jaeger: https://www.jaegertracing.io/docs/1.33/getting-started/
Jaeger-Client features: https://www.jaegertracing.io/docs/1.33/client-features/
Flask-OpenTracing: https://github.com/opentracing-contrib/python-flask
OpenTelemetry-Python: https://opentelemetry.io/docs/instrumentation/python/getting-started/

Using Finagle's clientbuilder, how do I set the host externally?

I am building a simple proxy to point to another server. Everything works but I need to find a way to be able to set the hosts in a ClientBuilder externally most likely using Docker or maybe some sort of configuration file. Here is what I have:
import java.net.InetSocketAddress
import com.twitter.finagle.Service
import com.twitter.finagle.builder.{ServerBuilder, ClientBuilder}
import com.twitter.finagle.http.{Request, Http}
import com.twitter.util.Future
import org.jboss.netty.handler.codec.http._
object Proxy extends App {
val client: Service[HttpRequest, HttpResponse] = {
ClientBuilder()
.codec(Http())
.hosts("localhost:8888")
.hostConnectionLimit(1)
.build()
}
val server = {
ServerBuilder()
.codec(Http())
.bindTo(new InetSocketAddress(8080))
.name("TROGDOR")
.build(client)
}
}
If you know of a way to do this or have any ideas about it please let me know!
if you want running this simple proxy in a docker container and manage the target host ip dynamically, you can try to pass a target host ip through environment variable and change your code like this
import java.net.InetSocketAddress
import com.twitter.finagle.Service
import com.twitter.finagle.builder.{ServerBuilder, ClientBuilder}
import com.twitter.finagle.http.{Request, Http}
import com.twitter.util.Future
import org.jboss.netty.handler.codec.http._
object Proxy extends App {
val target_host = sys.env.get("TARGET_HOST")
val client: Service[HttpRequest, HttpResponse] = {
ClientBuilder()
.codec(Http())
.hosts(target_host.getOrElse("127.0.0.1:8888"))
.hostConnectionLimit(1)
.build()
}
val server = {
ServerBuilder()
.codec(Http())
.bindTo(new InetSocketAddress(8080))
.name("TROGDOR")
.build(client)
}
}
this will let your code read system environment variable TARGET_HOST. when you done this part, you can try to start your docker container by adding the following parameter to your docker run command:
-e "TARGET_HOST=127.0.0.1:8090"
for example docker run -e "TARGET_HOST=127.0.0.1:8090" <docker image> <docker command>
note that you can change 127.0.0.1:8090 to your target host.
You need a file server.properties and put your configuration inside the file:
HOST=host:8888
Now get docker to write your configuration with every startup with a docker-entrypoint bash script. Add this script and define environment variables inside your Dockerfile:
$ ENV HOST=myhost
$ ENV PORT=myport
$ ADD docker-entrypoint.sh /docker-entrypoint.sh
$ ENTRYPOINT ["/docker-entrypoint.sh"]
$ CMD ["proxy"]
Write out your docker-entrypoint.sh:
#!/bin/bash -x
set -o errexit
cat > server.properties << EOF
HOST=${HOST}:${PORT}
EOF
if [ "$1" = 'proxy' ]; then
launch server
fi
exec "$#"
Launch Docker with your configuration and the command "proxy":
$ docker run -e "HOST=host" -e "PORT=port" image proxy
You can also do linking when your not sure of your server container ip adress:
$ docker run -e "HOST=mylinkhost" -e "PORT=port" --link myservercontainer:mylinkhost image proxy

Resources