Привет ребят, нужна консультация. Попалась задача, дано:
1) Инстанс Databricks (AWS) в UK
2) Копроративная финтех софтина в US
Цель: tokenized JDBC коннекшен m2m, возможность забирать датасеты из датабрикса в UK и писать в локальную базу в штатах.
Проблемы:
- Софтина не поддерживает Databricks нативно, но поддеживает дженерик JDBC коннехуны.
- Токены выдает пропиретарный ID провайдер и они экспйрятся каждый час.
Возможное решение: Питон апп, который будет ходить к местному Principal и просить токен, после чего включать счетчик и обновлять его каждый час. Токен размещать в ENV VAR сервера с софтиной, в JDBC URL connection template соответственно подсовывать ENV VAR где хранится полученный токен.
В теории, должно работать, но мне максимально не нравится секьюрность такого решения. В идеале, хотелось бы все это делать в рантайме, без записывания чего бы-то ни было куда бы-то ни было. Тоесть, сделать какой-то хендлер конкретно этого коннехуна и прям вот в открытой сессии подменивать токены.
Сразу хочу сказать, что это не совсем моя область знаний, поэтому и прошу советов.
А разве коннект не закрывается при не правильном токене ?
Если так, то возникнет проблема, что
1. Тебе полюбому нужно где-то локально хранить актуальный токен со временем экспайра, иначе остальные коннекты после обновления не будут иметь к нему доступа
2. В случае если у тебя с двух разных коннектов в +/- одно и то же время будет улетать запрос с заэкспайренным токеном, они оба отправят запрос на обновление и по итогу один перезапишет уже обновленный токен. Не смертельно, но очень сильно увеличит накладные расходы на число запросов.
Ну и я не совсем уверен, можно ли в уже установленной сессии на лету менять токен. Все-таки в нем содержится не только время экспайра, но и может быть куча служебной инфы, типа прав пользователя и т.д. и хз, можно ли на лету менять токен
DA, но мне это не нравится )
Ну и токен тогда, соответственно тоже держать в локальной переменной.
Но тут тогда будет проблема в том, что у потока1 есть токен А, который заэкспайрился и у потока2 есть токен А, который заэкспайрился.
поток1 отправлят запрос на обновление токена и получает токен С, перезаписывает себе время и все у него хорошо, потом поток 2 (до экспайра токена С) отправляет запрос, получает токен Д.
В итоге получаем что у потока 1 есть токен С который не заэкспайрился, но уже не действителен и вся схема ломается.
ЕМНИП, time to live зашивается в хэш, т.е он не может экспайрнуться ранее, чем выдваший его принципал позволит. А так, force renew можно просто захардкодить наверное.
Т.е. логика воркеров должна быть такая:
1. Получить у токен-сервиса токен.
2. Послать запрос с токеном.
3. Если в ответе "токен невалидный" — запросить у токен-сервиса новый токен с параметрами old_token=..., force_new_token=true
4. Повторить запрос с новым токеном
Логика токен-сервиса:
1. Запрос на токен: берем текущий токен из хранилища, отдаем. Если в хранилище нет токена — запрашиваем новый, ложим в хранилище, отдаем.
2. Запрос на обновление токена: ложим старый токен в хранилище, запрашиваем новый, отдаем. Если воркер прислал старый токен, который уже сохранен в хранилище — не запрашиваем новый, а отдаем новый из хранилища.
Надеюсь, пункт 2 понятно почему так сделан?
возможно нужно будет во всех образещениях к базе убедиться что можно подождать достаточно пока просят токен, если свой оверлей на дата_менеджмент, то ваще изи, не вижу ассинхронностей
еще вариант сделать не для токена переменную, а для состояния єкспайра токена, тогда все ассинхровые запросы будут ждать пока не поднимут флай из_токнг єкспайред и только тогда читать токен
Эхо из бана
13.10.2024, 18:30
В софтину можно подложить свой .jar файл? Тогда можно сделать свой JDBC драйвер-обёртку, который при подключении будет вычислять новые креденшилы.
ENV VAR так просто не поменяешь у java процесса без его перезапуска
>> который при подключении будет вычислять новые креденшилы.
Можешь чуть пояснить? Ты предлагаешь форкнуть датабриксовый jdbc драйвер?
Можно взять за основу это: https://github.com/aws/aws-secretsmanager-jdbc и изменить способ получения с AWS Secrets Manager на свой или не менять ничего и интегрироваться с AWS Secrets Manager.
в настройках будет типа такого:
jdbcUrl=jdbc-secretsmanager:postgresql://example.com:5432/database
Это же просто переменная. Я не быкую если что, но но если ты в коде указываешь на значение в ENV VAR, которое пусть даже меняется, зачем нам рестартать жвм? В этом же и весь смысл их использования.
В java без танцев с бубном нельзя поменять значение переменной окружения, можно только прочитать его.
Кстати ещё вариант - этот ваш шаблон URL поддерживает только переменные окружения? А например System properties он поддерживает? Тогда можно встроить в ваше приложение код, который будет по таймеру эти System properties обновлять. Тогда и обёртка не понадобится.
Ну он не наш, он датабриксовский. Я имею в виду в плане передаваемых параметров.
>> Тогда можно встроить в ваше приложение код, который будет по таймеру эти System properties обновлять.
Это интересная мысль! Смотри, есть условный системный объект в софтине, назовем его Connect. В нем собственно креды и URL до базы. Сама софтина от вендора, мы исходники трогать не можем. Но, мы можем трогать мету этой софтины, и есть большая доля вероятности что вот эти системные настройки хранятся в мета схеме, в уже локальной БД. И вот ее можно жмякать сколько угодно.
Даже когда совсем нет исходников, можно декомпилировать чужой код, посмотреть в каком поле URL хранится и где это поле используется. Если проприетарная библиотека вообще не поддерживает переменные в JDBC URL, всё ещё можно через Java Reflection по таймеру обновлять значение поля.
Скажем так, я 10 лет отработал на вендора, исходники у меня в голове)
>> То есть что можно использовать ENV VAR это чистое предположение?
Это просто самый тупой и самый простой способ, первое что пришло в голову.
>> можно декомпилировать чужой код, посмотреть в каком поле URL хранится и где это поле используется.
Я вот к этому и склоняюсь больше. Но допустим, нашли мы это поле, нет проблем, что мы дальше с ним будем делать? Мы возвращаемся к тому, что нужен однопоточный сервис, через который мы будем обновлять токены. Это в принципе вполне рабочий вариант, и за не имением других, наверное будем смотреть в эту сторону.
Энивей, оргромное спасибо - A66aT, nun-buoy, sprspr, drWolf, шоб вам молочка в кашку никогда не переливали :3 Жмякаю в обе щечки.