pass in null parameter from jdbctemplate

i have a query where some of the parameter is optional, something like

String PERMS = """
  select .....
  where ...
  and (:app is null or a.app=:app)
""";

this query and corresponding DAO method works fine when the parameter is not null, however would fail for both jdbctemplate or namedJdbcTemplate.

Turned out the trick is two folded:

  1. from the sql side, tell the dbms and its driver what’s the type of the optional parameter
String PERMS = """
  select .....
  where ...
  and (:app::text is null or a.app=:app)
""";

2. with namedjdbcTemplate, pass in the type (0) to the jdbc driver

MapSqlParamterSource params = ..
params.addValue("app", null, Types.NULL)

netflix dgs graphql with nginx

when dgs is running behind a reverse proxy, the graphiql is not working:

Expected behavior

When dgs is accessed directly, the graphiql is working.


When dgs is accessed from reverse proxy, the graphiql should work as well.

Actual behavior

When dgs is accessed from reverse proxy, the graphiql stopped working.


Steps to reproduce

  1. set up nginx as a reverse proxy, point /data to the backend dgs service (assume it’s dataprovider)
  2. access graphiql from http://<nginx_server>/data/graphiql

Note: A test case would be highly appreciated, but we understand that’s not always possible

Some RCA

The issue is due to in graphiql, its trying to fetch the graphql path as absolute path:

this would assume the graphql is at the root, which won’t be true with an existence of reverse proxy.

Possible Solution

The solution is to change that path to a relative path as ./graphql.

Isuse:

https://github.com/Netflix/dgs-framework/issues/1203

The fix is to point dgs graphiql at the relative path instead of root:

PR: https://github.com/Netflix/dgs-framework/pull/1204

With MR: #1204, and bump dgs version to 5.2.1, it’s now working both w/ and w/o reverse proxy.

w/


w/o


cname vs a record

cname:

A Canonical Name or CNAME record is a type of DNS record that maps an alias name to a true or canonical domain name. CNAME records are typically used to map a subdomain such as www or mail to the domain hosting that subdomain’s content.

https://support.google.com/a/answer/112037?hl=en#zippy=%2Cset-up-cname-records-now

vs a record

An A record maps a domain name to the IP address (Version 4) of the computer hosting the domain. An A record uses a domain name to find the IP address of a computer connected to the internet

https://support.dnsimple.com/articles/a-record/

the difference, in a nutshell, being, cname normally is an alias mapping to a single server. while A record should map to a list of servers, which could be load balanced.

nginx reverse proxy

I am using nginx to reverse proxy to some backend service (serviceX).

location /data {
   ...
  # rewrite ...
  proxy_pass http://backend
}

when client request for http://proxy/data/status, it should direct to http://backend/status

it took me really a long time to figure out (have tried with various rewrites), turns out the trick is to tell nginx when proxy_pass (http), it should pass the uri with a /, something like

location /data/ {
   proxy_pass http://backend/
}

gitlab breaking changes with cobertura

overnight, our gitlab pipeline has failed.

Turns out gitlab has pushed out a version (15+) with a breaking change.

https://about.gitlab.com/blog/2022/04/18/gitlab-releases-15-breaking-changes/#artifactsreportcobertura-keyword

https://gitlab.com/gitlab-org/gitlab/-/commit/812408bafae328b81652110fc53c6c6b89e3db81

the fix is not too difficult, but quite amazed by the breaking update without any notification (partially could be something to blame on our infra as well)

python configparser

it took me quite a while to figure out why the code below

from ConfigParser import ConfigParser
conf = ConfigParser()
conf.read(...)

was working in one codebase but not working in another codebase.

Turns out the package renamed to lower case (probably backward compatibility is never a concern in python ecosystem) in python3.

so above code worked for python 2, need to change to below for python 3

from configparser import ConfigParser
conf = ConfigParser()
conf.read(...)

(wondering how python ecosystem would look like if there is a version 4/5 in future).