Показаны сообщения с ярлыком glassfish. Показать все сообщения
Показаны сообщения с ярлыком glassfish. Показать все сообщения

суббота, 18 сентября 2010 г.

thread pools in glassfish v3

Пришло время переводить свои приложения с glassfish v2+ на glassfish v3+, при это естественно возникла куча проблем.
одна из них это то, что я использовал thread pool`ы GFv2. Эта часть не является частью стандарта javaee как скажем time services, и по этому api легко и непренужденно изменилось

В своем предыдущем посте я описывал как это делается в GFv2


...
        WorkManager workManager = WorkManagerFactory.getWorkManager("threadpoolname");
...
Поковырявшись в исходниках GFv2.1, посмотрим что же происходило на самом деле:
appserv-core/src/java/com/sun/enterprise/connectors/work/WorkManagerFactory.java:

...
    public static WorkManager getWorkManager(String poolName)
                              throws ConnectorRuntimeException {

        String className = null;
        String methodName = "getInstance";
        Class cls = null;
        WorkManager wm = null;

        try {
            className = System.getProperty(WORK_MANAGER_CLASS, DEFAULT);

            // Default work manager implementation is not a singleton.
            if (className.equals(DEFAULT)) {
                return new CommonWorkManager(poolName);
            }

            cls = Class.forName(className);
            if (cls != null) {
                Method method = cls.getMethod("getInstance", new Class[]{});
                wm = (WorkManager) method.invoke(cls, new Object[] {});
            }
        } catch (Exception e) {
            String msg = localStrings.getString("workmanager.instantiation_error");
            logger.log(Level.SEVERE, msg, e);
        }

        return wm;
    }
...

В последней версии GFv3, которую я смотрел [v3.1-b20-09_15_2010], в WorkManagerFactory нет такого метода, по этому можно просто руками сделать то же самое, хотя скорее всего это неправильно, но вот как это выглядит:

...
import com.sun.enterprise.connectors.ConnectorRuntime;
import com.sun.enterprise.connectors.work.CommonWorkManager;
...
workManager = new CommonWorkManager("threadpoolname", ConnectorRuntime.getRuntime(), "resourceAdapterName", resourceAdapter.getClass().getClassLoader());
...

эти классы находятся в библиотеках GLASSFISHv3_DIR/work-management.jar и GLASSFISHv3_DIR/connectors-runtime.jar

p.s. почитав код, не нашел как используются resourceAdapterName и classLoader, по этому в качестве resourceAdapterName использовал просто "fffuuu", а в качестве classLoader - this.getClass().getClassLoader()

вторник, 22 сентября 2009 г.

glassfish thread pool

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


для начала необходимо его создать, через веб консоль администрирования и дать ему имя:
Configuration -> Thread Pools -> New


использовать так:
...
import com.sun.enterprise.connectors.ConnectorRuntimeException;
import com.sun.enterprise.connectors.work.WorkManagerFactory;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkException;
import javax.resource.spi.work.WorkManager;
...
    try {
        WorkManager workManager = WorkManagerFactory.getWorkManager("threadpoolname");
        Work work = new Work() {
            @Override
            public void release() {
//вызывается если необходимо остановить тред
            }
 
            @Override
            public void run() {
//код, который надо распараллелить
            }
        };
        workManager.scheduleWork(work);
    } catch (WorkException e) {
//что-то сделать
} catch (ConnectorRuntimeException e) {
//что-то сделать
...
}
и не забудьте подключить библиотеку glassfish_dir/lib/appserv-rt.jar

пятница, 10 июля 2009 г.

manual javaee realm

Недавно я писал о том, как настроить jdbc realm в glassfish. Сейчас я попытаюсь рассказать, о том, как написать свой realm самому.

Итак, что же такое этот realm?
Realm - это такой механизм, отвечающий за аутентификацию пользователя на сервере приложений. Когда пользователь (точнее говорить principal) пытается получить доступ к какому-либо ресурсу сервера приложений, если для этого нужна авторизация, то realm используется для получения списка групп, в которых состоит пользователь. На основании этого списка решается - позволено ли данному пользователю воспользоваться данным ресурсом (будь то java-bean, jdbc-datasource и т.д.).

В совокупности с JAAS фреймворком они представляют собой подсистему аутентификации glassfish`а.

Для того, что бы написать свой realm для glassfish v2.1 необходимо реализовать два класса:

com.sun.appserv.security.AppservRealm
com.sun.appserv.security.AppservPasswordLoginModule

как вы их будите реализовывать, ваше дело, советую глянуть это и это в качестве примера

и добавить информацию о них в:

domain_dir/config/domain.xml
domain_dir/config/login.conf

замечание: для того что бы эти классы были видны в IDE я подкинул им пару jar-ов из glassfish`a, которые после билда можно исключить из списка файлов, т.к. они уже есть на сервере приложений:
glassfish_dir/lib/appserv-ext.jar
glassfish_dir/lib/appserv-rt.jar

понедельник, 11 мая 2009 г.

JDBC Realm в glassfish

Сегодня удачно создал и использовал jdbc realm в сервере приложений glassfish. Хотя возможность использовать такой тип realm`ов в glassfish`е появилась давно, отмечу скудную и запутанную документированность этой очень полезной фичи.

Начнем с того, что создадим таблички для jdbc-realm`а:
[в качестве операционной системы я использовал - OpenSolaris 5.11 snv_111a, в качестве RDBMS postgresql-8.3 доступный из стандартных репозиториев, сервер приложений Sun GlassFish Enterprise Server v2.1]

для начала я установил нужный jdbc driver для postgresql, (SUNWpostgr-jdbc) и положил его в ${DOMAIN_DIR}/lib/ext

затем создал необходимые таблички, содержащие пользователей и группы в моей БД, вот их структура
[структуру табличек глянул здесь]:

CREATE TABLE users (
user_name text,
user_password text NOT NULL,
CONSTRAINT PK_users PRIMARY KEY (user_name)
);
CREATE TABLE roles (
role_caption text,
CONSTRAINT PK_roles PRIMARY KEY (role_caption)
);
CREATE TABLE users_roles (
user_name text,
role_caption text,
CONSTRAINT PK_users_roles PRIMARY KEY (user_name, role_caption),
CONSTRAINT FK_users_roles_0 FOREIGN KEY (user_name) REFERENCES users(user_name),
CONSTRAINT FK_users_roles_1 FOREIGN KEY (role_caption) REFERENCES roles(role_caption)
);


Для опытов внесем туда что-нибудь:

INSERT INTO users VALUES ('ddosia', '63a9f0ea7bb98050796b649e85481845');
INSERT INTO roles VALUES ('root');
INSERT INTO users_roles VALUES ('ddosia', 'root');


далее создадим datasource, способный вытягивать данные из данной БД.
вначале создаем connection-pool при помощи веб-консоли администрирования:
"Resources"->"JDBC"->"Connection Pools":
кнопаем на "New", указываем имя ["pg_local"], resource type ["javax.sql.DataSource"] и database vendor ["PostgreSQL"];
вводим известные нам значения "ServerName", "DatabaseName", "PortNumber", "User", "Password"

"Resources"->"JDBC"->"JDBC Resources":
щелкаем "New", указываем JNDI-Name ["jdbc/pg"], выбираем "Pool Name" ["pg_pool"]

вуаля, пул готов, далее создадим realm, использующий данный пул:

с помошью консоли администрирования glassfish`а идем в "Configuration"->"Security"->"Realms", кнопаем на "New"
указываем имя ["myJDBCRealm"], "Class Name" ["com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm"]
далее заполняем след свойства:
JAAS context ["JDBCRealm"]
JNDI ["jdbc/pg"]
User Table ["users"]
User Name Column ["user_name"]
Password Column ["user_password"]
Group Table ["users_roles"]
Group Name Column ["role_caption"]

Теперь пришел черед самого приложения:
вначале создадим ejb-bean, что то типа:

TestBean.java:

package realmsample;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;

@Stateless (name="TestBean", mappedName="TestRemote")
public class TestBean implements TestRemote {
@RolesAllowed("root")
public String meth1() {
return "11111!!!!";
}
@PermitAll
public String meth2() {
return "22222!!!!";
}
}


TestRemote.java:

package realmsample;

import javax.ejb.Remote;

@Remote
public interface TestRemote {
public String meth1 ();
public String meth2 ();
}


Client.java:

...
try {
InitialContext ctx = new InitialContext();
TestRemote testBean = (TestRemote) ctx.lookup ("TestRemote#" + TestRemote.class.getName());
System.out.println(testBean.meth2());
System.out.println(testBean.meth1());
} catch (NamingException exc) {
exc.printStackTrace();
}
...

так же необходимо в sun-application.xml внести следующее

...
<realm>
myJDBCRealm
</realm>
...

и поставить галочку в
"Configuration"->"Security"
"Default Principal To Role Mapping" -> "Enabled"

собственно после того как все это задеплоить и запустить, например через java-web-start или через netbeans то появится диалоговое окно, которое попросит представится системе. После удачной аутентификиции и авторизации meth1 будет выполнятся только тем кто состоит в группе root, а meth2 любым авторизованным пользователям

воскресенье, 19 апреля 2009 г.

glassfish в opensolaris

Сегодня настраивал glassfish в opensolaris. Не скажу что этот процесс отличается чем-то от других ОС, но все же хотелось бы описать несколько специфичных шагов:
  1. устанавливаем, используя IPS:
    user@host:~# pkg install glassfishv2
  2. создаем директорию /var/appserver, назначаем на нее владельца, с правами которого будет запущено приложение
    user@host:~# mkdir /var/appserver; chmod 750 /var/appserver; chown appserv:appserv /var/appserver;
  3. создаем домен:
    appserv@host:~$ asadmin create-domain --user admin --adminport 4848 domain0
  4. сразу установим masterpassword:
    appserv@host:~$ asadmin change-master-password
  5. создадим следующие файлы, необходимые для генерации правил SMF, и наполним его необходимыми значениями:
    appserv@host:~$ echo "AS_ADMIN_USER=admin" > /var/appserver/passwd; echo "AS_ADMIN_PASSWORD=adminpassword" >> /var/appserver/passwd; echo "AS_ADMIN_MASTERPASSWORD=changeit" >> /var/appserver/passwd;
  6. затем добавим правило в SMF:
    user@host:~# asadmin create-service --passwordfile /var/appserver/passwd --serviceproperties net_privaddr /var/appserver/domains/domain0
  7. далее убедимся что сервис теперь доступен:
    appserv@host:~$ svcs -a | grep SUNWappserver
Небольшое пояснение некоторых моментов:
параметр
--serviceproperties net_privaddr позволяет слушать порты с номером меньшим чем 1024, что запрещено политикой безопасности по умолчанию

так же в документации говорится о дополнительном свойстве method_credential, позволяющим изменить пользователя, от имени которого будет запущен glassfish. Немного поэкспериментировав, я пришел к выводу что чего-то не то пишу, а именно:
asadmin create-service --passwordfile /var/appserver/passwd --serviceproperties method_credential=appserv --serviceproperties net_privaddr /var/appserver/domains/domain0
по этому, я просто напросто изменил руками нужный xml [/var/svc/manifest/application/SUNWappserver/domain0_var_appserver_domains/Domain-service-smf.xml], выгрузил уже использующийся [svccfg delete domain0] и загрузил его заново [svccfg import /var/svc/manifest/application/SUNWappserver/domain0_var_appserver_domains/Domain-service-smf.xml]