Правильный способ сделать источники данных / ресурсы настройкой времени развертывания - PullRequest
3 голосов
/ 26 февраля 2010

У меня есть веб-приложение, которое требует двух настроек:

  • Источник данных JDBC
  • Строковый токен

Я отчаянно хочу иметь возможность развернуть один .war в различных контейнерах (jetty, tomcat, gf3 минимум) и настроить эти параметры на уровне приложения внутри контейнера.

Мой код делает это:

InitialContext ctx = new InitialContext();
Context envCtx = (javax.naming.Context) ctx.lookup("java:comp/env");
token = (String)envCtx.lookup("token");
ds = (DataSource)envCtx.lookup("jdbc/datasource")

Давайте предположим, что я использовал интерфейс управления glassfish для создания двух ресурсов jdbc: jdbc / test-datasource и jdbc / live-datasource, которые подключаются к разным копиям одной и той же схемы, на разных серверах, с разными учетными данными и т. Д. Скажем, я Я хочу развернуть это на glassfish и указать на источник тестовых данных, это может быть в моем файле sun-web.xml:

...
<resource-ref>
  <res-ref-name>jdbc/datasource</res-ref-name>
  <jndi-name>jdbc/test-datasource</jndi-name>
</resource-ref>
...

но

  • sun-web.xml идет внутри моя война, верно?
  • наверняка должен быть способ сделать это через интерфейс управления

Я даже пытаюсь поступить правильно? Другие контейнеры делают это легче? Мне было бы особенно интересно узнать, как Jetty 7 справляется с этим, поскольку я использую его для разработки.

РЕДАКТИРОВАТЬ У Tomcat есть разумный способ сделать это:

Создать $TOMCAT_HOME/conf/Catalina/localhost/webapp.xml с:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true">
  <!-- String resource -->
  <Environment name="token" value="value of token" type="java.lang.String" override="false" />

  <!-- Linking to a global resource -->
  <ResourceLink name="jdbc/datasource1" global="jdbc/test" type="javax.sql.DataSource" />

  <!-- Derby -->
  <Resource name="jdbc/datasource2"
    type="javax.sql.DataSource"
    auth="Container"
    driverClassName="org.apache.derby.jdbc.EmbeddedDataSource"
    url="jdbc:derby:test;create=true"
    />

  <!-- H2 -->
  <Resource name="jdbc/datasource3"
    type="javax.sql.DataSource"
    auth="Container"
    driverClassName="org.h2.jdbcx.JdbcDataSource"
    url="jdbc:h2:~/test"
    username="sa"
    password=""
    />
</Context>

Обратите внимание, что override="false" означает обратное. Это означает, что этот параметр нельзя переопределить на web.xml.

Мне нравится этот подход, потому что файл является частью конфигурации контейнера , а не войной, но он не является частью глобальной конфигурации; это зависит от веб-приложения.

Полагаю, я ожидаю немного большего от glassfish, поскольку предполагается, что он имеет полноценный веб-интерфейс администратора, но я был бы достаточно доволен чем-то эквивалентным вышеописанному.

Ответы [ 3 ]

2 голосов
/ 17 марта 2010

Для GF v3 вы можете попробовать использовать опцию --deploymentplan подкоманды deploy asadmin. Это обсуждается на справочной странице для подкоманды deploy .

2 голосов
/ 09 сентября 2010

У нас была только эта проблема при переходе с Tomcat на Glassfish 3. Вот что у нас работает.

  • В консоли администратора Glassfish настройте источники данных (пулы и ресурсы соединений JDBC) для DEV / TEST / PROD / и т. Д.
  • Запишите параметры времени развертывания (в нашем случае информация о подключении к базе данных) в файле свойств. Например:
# Database connection properties
dev=jdbc/dbdev
test=jdbc/dbtest
prod=jdbc/dbprod
  • Каждое веб-приложение может загружать один и тот же файл свойств базы данных.
  • Найдите ресурс JDBC следующим образом.

import java.sql.Connection;
import javax.sql.DataSource;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * @param resourceName the resource name of the connection pool (eg jdbc/dbdev)
 * @return Connection a pooled connection from the data source 
 * associated with resourceName
 * @throws NamingException will be thrown if resource name is not found
 */
 public Connection getDatabaseConnection(String resourceName) 
             throws NamingException, SQLException {
    Context initContext = new InitialContext();
    DataSource pooledDataSource = (DataSource) initContext.lookup(resourceName);
    return pooledDataSource.getConnection();
 }

Обратите внимание, что это , а не обычный двухэтапный процесс, включающий поиск с использованием контекста именования "java: comp / env." Я понятия не имею, работает ли это в контейнерах приложений, отличных от GF3, но в GF3 нет необходимости добавлять дескрипторы ресурсов в web.xml при использовании вышеуказанного подхода.

0 голосов
/ 04 марта 2010

Я не уверен, что действительно понял вопрос / проблему.

Как Поставщик компонентов приложения , вы объявляете ресурсы, требуемые для вашего приложения, стандартным способом (независимость от контейнера) в web.xml.

Во время развертывания Application Deployer and Administrator должен следовать инструкциям поставщика 1011 * Application Component для разрешения внешних зависимостей (среди прочего ) например, путем создания источника данных на уровне сервера приложений и сопоставления его реального имени JNDI с именем ресурса, используемым приложением, с помощью дескриптора развертывания, специфичного для сервера приложений (например, sun-web.xml для GlassFish). Очевидно, что это специфичный для контейнера шаг, и, следовательно, он не охватывается спецификацией Java EE.

Теперь, если вы хотите изменить базу данных, которую использует приложение, вам нужно будет либо:

  • изменить отображение в дескрипторе развертывания сервера приложений - или -
  • изменить конфигурацию существующего источника данных, чтобы он указывал на другую базу данных.

Наличие интерфейса администратора ничего не меняет. Если я что-то пропустил, не стесняйтесь, дайте мне знать. И на всякий случай, может быть, взгляните на этот предыдущий ответ .

...