Статьи

Тестирование OpenLiberty с помощью Arquillian (Remote)

Услышав много хороших отзывов, я решил попробовать Open Liberty .

В этом посте я расскажу следующее:

  • Настройка Open Liberty
  • Настройка соединения JDBC
  • Настройка Arquillian
  • Тестирование конечной точки REST

Установка Open Liberty

На момент написания статьи я использовал Open Liberty 18.0.0.1 и Java SE 1.8.0_172 (PS стремился перейти на Java 9 и Java 10, но я подумал, что лучше подождать LTS Java 11).

Установка очень проста. Давайте предположим, что мы собираемся создать работающий test имени сервера.

Сначала распакуйте загрузку Open Liberty. Это создаст структуру wlp .

Перейдите в каталог bin и выполните следующую команду:

1
./server create test

Теперь test имени сервера была создана. Начать:

1
./server start test

с параметром test, являющимся именем сервера.

Перейдите по http://localhost:9080/test чтобы увидеть корневой контекст.

Остановиться,

1
./server stop test

Настроить server.xml

Как только вы запустите test сервер, в каталоге /usr/servers/test будет создан каталог, и внутри этого каталога будет файл с именем server.xml . Давайте проверим это.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
 
    <!-- Enable features -->
    <featureManager>
        <feature>jsp-2.3</feature>
    </featureManager>
 
    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint id="defaultHttpEndpoint"
                  httpPort="9080"
                  httpsPort="9443" />
 
    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>
</server>

В этой статье мы используем веб-профиль Java EE 7, чтобы сделать это очень просто (и даже не нужно перезагружать сервер). Просто измените featureManager .

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
 
    <!-- Enable features -->
    <featureManager>
        <feature>webProfile-7.0</feature>
    </featureManager>
 
    <!-- the rest of the configuration omitted -->

Вы можете проверить, какие функции загружаются динамически, посмотрев на console.log .

Конфигурирование источника данных JDBC

Настройте источник данных в server.xml

Для этого упражнения я использую MySQL 8.0. Настройка MySQL и его настройка выходит за рамки этой статьи.

Давайте предположим, что мы создали новую базу данных, которая также называется test .

Чтобы настроить источник данных, внесите следующую модификацию в ваш server.xml и перезапустите (или нет, не слишком уверен в этом, но без перезапуска не повредит).

Комментарии чередуются.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="3.0" encoding="UTF-8"?>
<server description="new server">
 
    <!-- Enable features -->
    <featureManager>
        <feature>webProfile-7.0</feature>
    </featureManager>
 
    <!-- Declare the jar files for MySQL access through JDBC. -->
    <dataSource id="testDS" jndiName="jdbc/testDS">
        <jdbcDriver libraryRef="MySQLLib"/>
        <properties databaseName="test"
                  serverName="localhost" portNumber="3306"
                  user="root" password="P4sswordGoesH3r3"/>
    </dataSource>
    <library id="MySQLLib">
        <file name="/home/dwuysan/dev/appservers/wlp/usr/shared/resources/mysql/mysql-connector-java-8.0.11.jar"/>
    </library>
 
    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>
</server>

persistence.xml

OpenLiberty поставляется с EclipseLink, поставляемым в качестве поставщика JPA. В этом примере я не настроил никаких свойств EclipseLink.

01
02
03
04
05
06
07
08
09
10
11
<?xml version="1.0" encoding="UTF-8"?>
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="2.1">
    <persistence-unit name="testPU">
        <jta-data-source>jdbc/testDS</jta-data-source>       
        <properties>
        </properties>
    </persistence-unit>
</persistence>

И затем вы можете вызвать его в приложении Java EE через:

01
02
03
04
05
06
07
08
09
10
11
@Stateless
@LocalBean
public class LogService {
 
    @PersistenceContext
    private EntityManager em;
 
    public Collection<Log> getLogs() {
        return this.em.createNamedQuery(Log.FIND_ALL, Log.class).getResultList();
    }
}

Настройка Arquillian

В этой статье мы собираемся реализовать удаленное тестирование Arquillian на работающем сервере OpenLiberty.

Во-первых, добавьте arquillian в ваш pom.xml .

Настройте pom.xml

Это pom.xml, который был изменен:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>id.co.lucyana</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
 
    <name>test</name>
 
    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
     
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>1.4.0.Final</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
    <dependencies>       
        <dependency>
            <groupId>org.jboss.arquillian.graphene</groupId>
            <artifactId>graphene-webdriver</artifactId>
            <version>2.3.2</version>
            <type>pom</type>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <scope>test</scope>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.junit</groupId>
            <artifactId>arquillian-junit-container</artifactId>
            <scope>test</scope>
        </dependency>       
        <dependency>
            <!-- Arquillian WebSphere Liberty Profile support -->
            <groupId>io.openliberty.arquillian</groupId>
            <artifactId>arquillian-liberty-remote</artifactId>
            <version>1.0.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
     
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Внесите изменения в server.xml

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
 
    <!-- Enable features -->
    <featureManager>
        <feature>webProfile-7.0</feature>
        <feature>restConnector-2.0</feature>
    </featureManager>
     
    <!-- Declare the jar files for MySQL access through JDBC. -->
    <dataSource id="testDS" jndiName="jdbc/testDS">
        <jdbcDriver libraryRef="MySQLLib"/>
        <properties databaseName="test"
                  serverName="localhost" portNumber="3306"
                  user="root" password="P4sswordGoesH3r3"/>
    </dataSource>
    <library id="MySQLLib">
        <file name="/home/dwuysan/dev/appservers/wlp/usr/shared/resources/mysql/mysql-connector-java-8.0.11.jar"/>
    </library>
 
    <httpEndpoint httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint" host="*" />
 
    <!-- userName and password should also be set in arquillian.xml to these values -->
    <quickStartSecurity userName="admin" userPassword="admin" />
 
    <!-- Enable the keystore -->
    <keyStore id="defaultKeyStore" password="password" />
 
    <applicationMonitor updateTrigger="mbean" />
    <logging consoleLogLevel="INFO" />
 
    <!-- This section is needed to allow upload of files to the dropins directory, the remote container adapter relies on this configuration -->
    <remoteFileAccess>
        <writeDir>${server.config.dir}/dropins</writeDir>
    </remoteFileAccess>
 
    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>
</server>

Доверяйте серверу (то есть сертификату)

Вам также нужно, чтобы эти ключи доверяли вашему клиенту, в противном случае вы увидите ошибки доверия сертификатам SSL, и вам нужно дать разрешения адаптеру контейнера для записи в каталог dropins » (Liberty-Arquillian 2018)

После того, как вы произвели все необходимые изменения выше (и перезапустите сервер), обратите внимание, что в каталоге <location of your OpenLiberty server>/usr/servers/test/resources/security создан новый каталог <location of your OpenLiberty server>/usr/servers/test/resources/security с именем test сервера мы изначально создали.

Обратите внимание, что создаются два файла, keys.jks и ltpa.keys . Теперь нас интересует keys.jks .

Чтобы мы могли запустить наш тест из Netbeans (Maven), JDK должен доверять запущенному OpenLiberty.

Проверьте сертификат

1
2
keytool -list -v -keystore key.jks
Enter keystore password:

password здесь в основном то, что мы создали в нашем server.xml, особенно в этой строке:

1
2
<!-- Enable the keystore -->
<keyStore id="defaultKeyStore" password="password" />

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
*****************  WARNING WARNING WARNING  *****************
* The integrity of the information stored in your keystore  *
* has NOT been verified!  In order to verify its integrity, *
* you must provide your keystore password.                  *
*****************  WARNING WARNING WARNING  *****************
 
Keystore type: jks
Keystore provider: SUN
 
Your keystore contains 1 entry
 
Alias name: default
Creation date: May 26, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=localhost, OU=test, O=ibm, C=us
Issuer: CN=localhost, OU=test, O=ibm, C=us
Serial number: 2a6c5b27
Valid from: Sat May 26 12:24:30 WITA 2018 until: Sun May 26 12:24:30 WITA 2019
Certificate fingerprints:
     MD5:  63:92:B2:4A:25:E3:BB:3B:96:37:11:C1:A7:25:38:B5
     SHA1: B6:38:95:88:FC:50:EC:A0:8E:41:4E:DE:B5:D4:8B:85:2E:61:A2:5F
     SHA256: 9C:7B:6A:FA:46:8C:50:F2:7D:7B:C4:24:4B:15:78:5A:34:25:C8:43:D1:AB:4D:EE:C7:00:4C:AF:30:F5:5C:92
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
 
Extensions:
 
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 88 F2 C2 32 73 73 B6 66   8F FA 42 85 1F 43 A5 AF  ...2ss.f..B..C..
0010: 84 33 62 D5                                        .3b.
]
]
 
 
 
*******************************************
*******************************************

Далее экспортируем сертификат

Теперь нам нужно создать .cer . Используйте следующую команду:

1
2
keytool -export -alias default -file testwlp.crt -keystore key.jks
Enter keystore password:

В основном мы экспортируем сертификат alias в файл с именем testwlp.crt . Теперь файл с именем testwlp.crt должен быть создан.

Наконец, давайте доверять этому сертификату, импортировав этот сертификат в JDK cacert

1
keytool -import -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias testwlp -import -file testwlp.crt

PS Обратите внимание, что, как отмечают многие эксперты (через Twitter), очевидно, существует много способов «доверять» серверу. Я уверен, что есть лучшие способы, и я бы предпочел не трогать файлы JDK.

Создать arquillian.xml

Теперь, когда все эти работы выполнены, давайте добавим arquillian.xml соответственно.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="UTF-8"?>
    <engine>
        <property name="deploymentExportPath">target</property>
    </engine>
    <container qualifier="liberty-remote" default="true">
        <configuration>
            <property name="hostName">localhost</property>
            <property name="serverName">test</property>
 
            <!-- check the 'quickStartSecurity' on 'server.xml' -->
            <property name="username">admin</property>
            <property name="password">admin</property>
 
            <!-- check the 'server.xml' -->
            <property name="httpPort">9080</property>
            <property name="httpsPort">9443</property>
        </configuration>
    </container>   
    <extension qualifier="webdriver">
        <!--<property name="browser">firefox</property>-->
        <property name="remoteReusable">false</property>
    </extension>
</arquillian>

Напишите тестовый набор REST

Сделав все эти настройки, вы можете написать тестовый пример Arquillian. Ниже приведен пример контрольного примера для конечной точки JAX-RS (извините за простоту контрольного примера, цель в том, чтобы показать, как мы можем тестировать использование Arquillian-remote против OpenLiberty) :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package id.co.lucyana.test.resource;
 
import id.co.lucyana.test.entity.Log;
import id.co.lucyana.test.services.LogService;
import id.co.lucyana.test.util.ApplicationConfig;
import java.net.URL;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
 
@RunWith(Arquillian.class)
public class LogResourceTest {
     
    @Drone
    private WebDriver webDriver;
 
    @Deployment
    public static JavaArchive createTestArchive() {
        return ShrinkWrap.create(JavaArchive.class)
                .addClass(Log.class)
                .addClass(LogResource.class)
                .addClass(LogService.class)
                .addClass(ApplicationConfig.class)
                .addAsManifestResource("test-persistence.xml",
                        ArchivePaths.create("persistence.xml"));
    }
 
    @Test
    @RunAsClient
    public void testLogResource(@ArquillianResource URL url) {       
        this.webDriver.get(url.toString() + "resources/log");
        String pageSource = this.webDriver.getPageSource();
        System.out.println("RESULT: " + pageSource);
        Assert.assertTrue(true);
    }
}

Рекомендации

DigiCert, 2018, «Как установить доверенный корень в хранилище ключей Java cacerts» , DigiCert, доступ 20 июня 2018

Liberty-Arquillian, 2018, «Arquillian Liberty Remote Documentation» , GitHub. Inc, доступ 20 июня 2018

SSLShopper, 2008, «Наиболее распространенные команды хранилища ключей Java Keytool» , SSLShopper, доступ к 20 июня 2018 года

Опубликовано на Java Code Geeks с разрешения Дени Вуйсана, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Тестирование OpenLiberty с Arquillian (Remote)

Мнения, высказанные участниками Java Code Geeks, являются их собственными.