[KEYCLOAK-15692] Upgrade to Wildfly "21.0.1.Final"

Base fixes:
* [KEYCLOAK-15780]      Upgrade Keycloak to Wildfly 21.0.0.Beta1 / Wildfly Core 13.0.0.Beta6
* [KEYCLOAK-16031]      Upgrade Keycloak to Wildfly 21.0.0.Final / Wildfly Core 13.0.1.Final
* [KEYCLOAK-16442]      Upgrade Keycloak to Wildfly 21.0.1.Final / Wildfly Core 13.0.3.Final

Other (dependent) fixes:
* [KEYCLOAK-15408]      Deprecate former Wildfly and Wildfly Core versions in Arquillian's
                        testsuite pom.xml file as part of the upgrade script
* [KEYCLOAK-15442]      Update the version of 'jboss-parent' as part of the Wildfly upgrade
                        script if necessary
* [KEYCLOAK-15474]      Add --verbose and --force options to the Wildfly upgrade automated script
* [KEYCLOAK-15649]      Update "urn:jboss:domain:infinispan:10.0" version as part of the Wildfly
                        upgrade automated script
* [KEYCLOAK-15652]      Wildfly upgrade automated script - Align Python artifact version
                        comparsion algorithm with the Maven / Java one

Signed-off-by: Jan Lieskovsky <jlieskov@redhat.com>
This commit is contained in:
Jan Lieskovsky 2020-09-02 15:29:07 +02:00 committed by Stian Thorgersen
parent 5c2122d36f
commit 833bf98643
68 changed files with 1672 additions and 1966 deletions

4
.gitignore vendored
View file

@ -77,3 +77,7 @@ target
# testsuite #
#############
*offline-token.txt
# Quarkus ephemeral data #
##########################
quarkus/data/*.db

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
@ -21,7 +21,7 @@
<parent>
<groupId>org.jboss</groupId>
<artifactId>jboss-parent</artifactId>
<version>35</version>
<version>37</version>
</parent>
<groupId>org.keycloak.bom</groupId>

View file

@ -87,8 +87,7 @@ public class CertificateUtils {
Date notAfter = new Date(System.currentTimeMillis() + (((1000L * 60 * 60 * 24 * 30)) * 12) * 3);
// SubjectPublicKeyInfo
SubjectPublicKeyInfo subjPubKeyInfo = new SubjectPublicKeyInfo(ASN1Sequence.getInstance(keyPair.getPublic()
.getEncoded()));
SubjectPublicKeyInfo subjPubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(new X500Name(caCert.getSubjectDN().getName()),
serialNumber, notBefore, notAfter, subjectDN, subjPubKeyInfo);

View file

@ -18,7 +18,7 @@
package org.keycloak.common.util;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -131,7 +131,7 @@ public final class PemUtils {
try {
StringWriter writer = new StringWriter();
PEMWriter pemWriter = new PEMWriter(writer);
JcaPEMWriter pemWriter = new JcaPEMWriter(writer);
pemWriter.writeObject(obj);
pemWriter.flush();
pemWriter.close();

View file

@ -18,23 +18,35 @@
package org.keycloak;
import junit.framework.Assert;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v1CertificateBuilder;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.x509.X509V1CertificateGenerator;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
import org.bouncycastle.operator.OperatorCreationException;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.Time;
import org.keycloak.common.VerificationException;
import org.keycloak.jose.jws.JWSBuilder;
import org.keycloak.representations.AccessToken;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.TokenUtil;
import javax.security.auth.x500.X500Principal;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
@ -43,8 +55,8 @@ import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Security;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.security.auth.x500.X500Principal;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -62,24 +74,43 @@ public class RSAVerifierTest {
if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider());
}
public static X509Certificate generateTestCertificate(String subject, String issuer, KeyPair pair) throws InvalidKeyException,
NoSuchProviderException, SignatureException {
public static X509Certificate generateTestCertificate(String subject, String issuer, KeyPair pair)
throws CertificateException, InvalidKeyException, IOException,
NoSuchProviderException, OperatorCreationException,
SignatureException
{
X500Name issuerDN = new X500Name("CN=" + issuer);
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
Date notBefore = new Date(System.currentTimeMillis() - 10000);
Date notAfter = new Date(System.currentTimeMillis() + 10000);
X500Name subjectDN = new X500Name("CN=" + subject);
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo
.getInstance(pair.getPublic().getEncoded());
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
X509v1CertificateBuilder builder = new X509v1CertificateBuilder(
issuerDN, serialNumber, notBefore, notAfter, subjectDN, subjectPublicKeyInfo
);
certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
certGen.setIssuerDN(new X500Principal(issuer));
certGen.setNotBefore(new Date(System.currentTimeMillis() - 10000));
certGen.setNotAfter(new Date(System.currentTimeMillis() + 10000));
certGen.setSubjectDN(new X500Principal(subject));
certGen.setPublicKey(pair.getPublic());
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder()
.find("SHA256WithRSAEncryption");
return certGen.generateX509Certificate(pair.getPrivate(), "BC");
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder()
.find(sigAlgId);
ContentSigner signer = new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
.build(PrivateKeyFactory.createKey(pair.getPrivate().getEncoded()));
X509CertificateHolder holder = builder.build(signer);
return new JcaX509CertificateConverter().getCertificate(holder);
}
@BeforeClass
public static void setupCerts() throws NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException {
public static void setupCerts()
throws CertificateException, InvalidKeyException, IOException,
NoSuchAlgorithmException, NoSuchProviderException,
OperatorCreationException, SignatureException
{
badPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
idpPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
idpCertificates = new X509Certificate[]{generateTestCertificate("CN=IDP", "CN=IDP", idpPair)};
@ -101,7 +132,7 @@ public class RSAVerifierTest {
public void testPemWriter() {
PublicKey realmPublicKey = idpPair.getPublic();
StringWriter sw = new StringWriter();
PEMWriter writer = new PEMWriter(sw);
JcaPEMWriter writer = new JcaPEMWriter(sw);
try {
writer.writeObject(realmPublicKey);
writer.flush();

View file

@ -26,66 +26,66 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-annotations/jackson-annotations-2.10.4/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-annotations/jackson-annotations-2.10.5/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-core/jackson-core-2.10.4/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-core/jackson-core-2.10.5/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-databind/jackson-databind-2.10.4/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-databind/jackson-databind-2.10.5/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.4/json/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.5/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.4/json/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.5/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.4/json/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.5/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>

View file

@ -26,77 +26,66 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-annotations/jackson-annotations-2.10.4/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-annotations/jackson-annotations-2.10.5/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-core/jackson-core-2.10.4/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-core/jackson-core-2.10.5/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-databind/jackson-databind-2.10.4/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-databind/jackson-databind-2.10.5/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.4/json/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.5/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.4/json/src/main/resources/META-INF/LICENSE</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.5/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.10.4</version>
<version>2.10.5</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.4/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://git-wip-us.apache.org/repos/asf?p=httpcomponents-client.git;a=blob_plain;f=LICENSE.txt;hb=refs/tags/rel/v4.5.12</url>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.10.5/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
@ -111,17 +100,6 @@
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://git-wip-us.apache.org/repos/asf?p=httpcomponents-core.git;a=blob_plain;f=LICENSE.txt;hb=refs/tags/rel/v4.4.13</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>

View file

@ -1,558 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================================================
This project includes Public Suffix List copied from
<https://publicsuffix.org/list/effective_tld_names.dat>
licensed under the terms of the Mozilla Public License, v. 2.0
Full license text: <http://mozilla.org/MPL/2.0/>
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View file

@ -1,178 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View file

@ -89,17 +89,6 @@
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12.redhat-00001</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://git-wip-us.apache.org/repos/asf?p=httpcomponents-client.git;a=blob_plain;f=LICENSE.txt;hb=refs/tags/rel/v4.5.12</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
@ -111,17 +100,6 @@
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13.redhat-00001</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://git-wip-us.apache.org/repos/asf?p=httpcomponents-core.git;a=blob_plain;f=LICENSE.txt;hb=refs/tags/rel/v4.4.13</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>

View file

@ -1,558 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
=========================================================================
This project includes Public Suffix List copied from
<https://publicsuffix.org/list/effective_tld_names.dat>
licensed under the terms of the Mozilla Public License, v. 2.0
Full license text: <http://mozilla.org/MPL/2.0/>
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View file

@ -1,178 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View file

@ -17,7 +17,7 @@
~ limitations under the License.
-->
<domain xmlns="urn:jboss:domain:10.0">
<domain xmlns="urn:jboss:domain:14.0">
<extensions>
<?EXTENSIONS?>

View file

@ -22,7 +22,7 @@
is also started by this host controller file. The other instance must be started
via host-slave.xml
-->
<host name="master" xmlns="urn:jboss:domain:10.0">
<host name="master" xmlns="urn:jboss:domain:14.0">
<extensions>
<?EXTENSIONS?>
</extensions>

View file

@ -17,7 +17,7 @@
~ limitations under the License.
-->
<host xmlns="urn:jboss:domain:10.0">
<host xmlns="urn:jboss:domain:14.0">
<extensions>
<?EXTENSIONS?>
</extensions>

View file

@ -23,7 +23,7 @@
via host-slave.xml
-->
<host name="master" xmlns="urn:jboss:domain:10.0">
<host name="master" xmlns="urn:jboss:domain:14.0">
<extensions>
<?EXTENSIONS?>
</extensions>

View file

@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:10.0">
<server xmlns="urn:jboss:domain:14.0">
<extensions>
<?EXTENSIONS?>

View file

@ -782,4 +782,18 @@ if (result != org.keycloak.keycloak-model-infinispan) of /subsystem=infinispan/c
echo
end-if
# Migrate from 11.0.0 to 12.0.0
if (result != expression "${jboss.mail.server.host:localhost}") of /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:read-attribute(name=host)
echo Adding host expression to the SMTP configuration of a remote destination outbound socket binding in the mail subsystem
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:write-attribute(name=host, value=expression "${jboss.mail.server.host:localhost}")
echo
end-if
if (result != expression "${jboss.mail.server.port:25}") of /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:read-attribute(name=port)
echo Adding port expression to the SMTP configuration of a remote destination outbound socket binding in the mail subsystem
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:write-attribute(name=port, value=expression "${jboss.mail.server.port:25}")
echo
end-if
echo *** End Migration ***

View file

@ -647,4 +647,18 @@ if (result != org.keycloak.keycloak-model-infinispan) of /subsystem=infinispan/c
echo
end-if
# Migrate from 11.0.0 to 12.0.0
if (result != expression "${jboss.mail.server.host:localhost}") of /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:read-attribute(name=host)
echo Adding host expression to the SMTP configuration of a remote destination outbound socket binding in the mail subsystem
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:write-attribute(name=host, value=expression "${jboss.mail.server.host:localhost}")
echo
end-if
if (result != expression "${jboss.mail.server.port:25}") of /socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:read-attribute(name=port)
echo Adding port expression to the SMTP configuration of a remote destination outbound socket binding in the mail subsystem
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=mail-smtp:write-attribute(name=port, value=expression "${jboss.mail.server.port:25}")
echo
end-if
echo *** End Migration ***

View file

@ -28,7 +28,7 @@ To use, simply 'import wildfly.upgrade' and call the necessary routines.
import colorlog, copy, itertools, logging, lxml.etree, os, os.path, re, sys
from packaging.version import parse as parseVersion
from importlib import import_module
from shutil import copyfileobj
from subprocess import check_call, check_output
from tempfile import NamedTemporaryFile
@ -36,12 +36,14 @@ from urllib.request import HTTPError, urlopen
__all__ = [
'getElementsByXPath',
'getElementsByXPathFromRemoteXml',
'getKeycloakGitRepositoryRoot',
'getModuleLogger',
'getStepLogger',
'getTaskLogger',
'getPomDependencyByArtifactId',
'getPomProperty',
'getPomPropertyFromRemoteXml',
'getVersionOfPomDependency',
'getXmlRoot',
'isWellFormedWildflyTag',
@ -49,23 +51,55 @@ __all__ = [
'loadGavDictionaryFromXmlFile',
'saveUrlToNamedTemporaryFile'
'updateAdapterLicenseFile',
'updateMainKeycloakPomFile'
'performMainKeycloakPomFileUpdateTask',
'performKeycloakAdapterLicenseFilesUpdateTask',
'synchronizeInfinispanSubsystemXmlNamespaceWithWildfly'
]
__author__ = "Jan Lieskovsky <jlieskov@redhat.com>"
__loglevel__ = logging.INFO
__status__ = "Alpha"
__version__ = "0.0.1"
__version__ = "0.0.2"
#
# Various data structures for the module
# Various constants / data structures for the module
#
# Empty string
_empty_string = ''
# Base URL of the Keycloak's main pom.xml file from GitHub master branch
_keycloak_github_master_main_pom_base_url = "https://raw.githubusercontent.com/keycloak/keycloak/master/pom.xml"
# Python implementation of the Maven artifact versions comparator
_maven_version_comparator_ = import_module(
'lib.wildfly.upgrade.dependencies.3rd_party.fabric8-analytics-version-comparator.f8a_version_comparator'
)
# GitHub raw form of the base URL to the specific Wildfly tag repository root
# Note: To get the final version of the URL '%s' format specifier needs to be
# expanded to a particular Wildfly tag / release!
_wildfly_github_raw_base_url_for_tag = (
'https://raw.githubusercontent.com/wildfly/wildfly/%s/'
)
# Base URL of the Wildfly's main pom.xml XML file from GitHub tag branch
_wildfly_github_tag_main_pom_base_url = (
_wildfly_github_raw_base_url_for_tag +
'pom.xml'
)
# Base URL of the Wildfly's Infinispan subsystem-template XML file from GitHub
# tag branch
_wildfly_github_tag_ispn_subtempl_base_url = (
_wildfly_github_raw_base_url_for_tag +
'clustering/infinispan/extension/src/main/resources/subsystem-templates/infinispan.xml'
)
# POM namespace prefix definition for lxml
_pom_ns = "http://maven.apache.org/POM/4.0.0"
# Module loggers
_moduleLoggers = {}
# 'pom' namespace prefix definition for lxml
_pom_ns = "http://maven.apache.org/POM/4.0.0"
# Maven GAV (groupId:artifactId:version) related stuff
_gav_elements = ['groupId', 'artifactId', 'version']
# Maven GAV (groupId:artifactId:version) related constants / data structures
_gav_delimiter = ':'
_gav_elements = ['groupId', 'artifactId', 'version']
#
# Various base helper routines
@ -119,14 +153,18 @@ def _emptyNewLine():
"""
print()
def _logErrorAndExitIf(errorMessage, condition):
def _logErrorAndExitIf(errorMessage, condition, logger = None):
"""
Log particular error message and exit with error if specified condition was
met.
Log particular error message using either the default or custom logger
specified via the 'logger' parameter, and exit with error if the specified
condition was met.
"""
# Use the default logger if a custom one wasn't requested
if logger is None:
logger = getModuleLogger()
if condition:
_emptyNewLine()
getModuleLogger().error(errorMessage)
logger.error(errorMessage)
_emptyNewLine()
sys.exit(1)
@ -143,7 +181,7 @@ def setupLogger(loggerName = 'upgrade-wildfly', loggerFormatter = '%(log_color)s
stdOutLogHandler.setFormatter(loggerFormatter)
logger = logging.getLogger(loggerName)
logger.addHandler(stdOutLogHandler)
logger.setLevel(logging.INFO)
logger.setLevel(__loglevel__)
return logger
@ -168,7 +206,7 @@ def getTaskLogger(taskLoggerName):
"""
Return custom logger handling (sub)tasks.
"""
taskLogFormatter = '\n%(log_color)s[%(levelname)s] [%(name)s] Performing Task:\n\n\t%(message)s\n'
taskLogFormatter = '\n%(log_color)s[%(levelname)s] [%(name)s]\n\n\t%(message)s\n'
return getLogger(loggerName = taskLoggerName, loggerFormatter = taskLogFormatter)
def getStepLogger():
@ -187,13 +225,35 @@ def getStepLogger():
def getElementsByXPath(xmlTree, xPath, nameSpace = { "pom" : "%s" % _pom_ns }):
"""
Given the XML tree return the list of elements matching the 'xPath' from
the XML 'nameSpace'. 'nameSpace' is optional argument. If not specified
defaults to the POM XML namespace.
the XML 'nameSpace'.
Returns empty list if no such element specified by 'xPath' is found.
'nameSpace' is optional argument. If not specified defaults to the POM XML
namespace.
Returns empty list if no such element matching the specified by 'xPath' is
found.
"""
return xmlTree.xpath(xPath, namespaces = nameSpace)
def getElementsByXPathFromRemoteXml(xmlUrl, xPath, nameSpace = { "pom" : "%s" % _pom_ns }, errorMessage = None, expectedElementsCount = None):
"""
Given the URL of the remote XML file as 'xmlUrl' return the list of
elements matching the 'xPath' from the XML 'nameSpace'.
'nameSpace' is optional argument. If not specified defaults to the POM XML
namespace.
Returns empty list if no such element matching the specified by 'xPath' is
found.
"""
xmlFile = saveUrlToNamedTemporaryFile(xmlUrl)
xmlRoot = getXmlRoot(xmlFile)
xmlElements = getElementsByXPath(xmlRoot, xPath, nameSpace = nameSpace)
if None not in (errorMessage, expectedElementsCount) and len(xmlElements) != expectedElementsCount:
_logErrorAndExitIf(errorMessage, True)
return xmlElements
def getPomDependencyByArtifactId(xmlTree, artifactIdText):
"""
Given the XML tree return list of POM dependency elements matching
@ -212,6 +272,31 @@ def getPomProperty(xmlTree, propertyText):
"""
return xmlTree.xpath('/pom:project/pom:properties/pom:%s' % propertyText, namespaces = { "pom" : "%s" % _pom_ns })
def getPomPropertyFromRemoteXml(xmlUrl, propertyText, errorMessage = None, expectedElementsCount = None):
"""
Given the URL of the remote XML file as 'xmlUrl' and name of the property
to be retrieved from the XML file as 'propertyText' perform:
* Save the remote XML to local file,
* Obtain the XML root from the content,
* Locate the specified POM property element within the file.
Moreover, if both 'errorMessage' and 'expectedElementsCount' are provided,
display the 'errorMessage' error message and exit with failure if the count
of found elements matching the 'propertyText' doesn't match the
'expectedElemsCount' value.
Returns list of matching property elements or exits with error if count
other than specified in 'expectedElementsCount' is found.
"""
xmlFile = saveUrlToNamedTemporaryFile(xmlUrl)
xmlRoot = getXmlRoot(xmlFile)
propertyElement = getPomProperty(xmlRoot, propertyText)
if None not in (errorMessage, expectedElementsCount) and len(propertyElement) != expectedElementsCount:
_logErrorAndExitIf(errorMessage, True)
return propertyElement
def getVersionOfPomDependency(xmlElem, groupIdText, artifactIdText):
"""
Given the list of XML POM dependency elements, return the value of
@ -257,6 +342,23 @@ def getXmlRoot(filename):
# performed within a Wildfly upgrade
#
def compareMavenVersions(updatedVersion, currentVersion):
"""
Compare 'updatedVersion' with 'currentVersion' using the generic Maven
version comparison method.
Return a negative integer, zero, or a positive integer as the
'updatedVersion' is less than, equal to, or greater than the
'currentVersion'.
"""
comparableVersion = (
_maven_version_comparator_
.comparable_version
.ComparableVersion(updatedVersion)
)
return comparableVersion.compare_to(currentVersion)
def getProductNamesForKeycloakPomProfile(profile = 'community'):
"""
Return values of <product.name> and <product.name.full> elements
@ -418,7 +520,7 @@ def loadGavDictionaryFromXmlFile(xmlFile, xPathPrefix = '/pom:project/pom:depend
# 'project.version' value. Create a custom XPath query to fetch the actual numeric value
if not propertyElem:
# Build xpath from version value, turn e.g. 'project.version' to '/pom:project/pom:version'
customXPath = ''.join(list(map(lambda x: '/pom:' + x, gavDictValue.split('.'))))
customXPath = _empty_string.join(list(map(lambda x: '/pom:' + x, gavDictValue.split('.'))))
# Fetch the numeric version
propertyElem = getElementsByXPath(xmlRoot, customXPath)
# Exit with error if it wasn't possible to determine the artifact version even this way
@ -466,7 +568,7 @@ def mergeTwoGavDictionaries(firstGavDictionary, secondGavDictionary):
# Update the artifact version in resulting GAV dictionary only if
# the value from the second dictionary is higher than the current
# one
if parseVersion(secondDictValue) > parseVersion(currentValue):
if compareMavenVersions(secondDictValue, currentValue) > 0:
unitedGavDictionary[secondDictKey] = secondDictValue
except KeyError:
@ -560,6 +662,7 @@ _keycloakSpecificProperties = [
"spring-boot15.version",
"spring-boot21.version",
"spring-boot22.version",
"spring-boot23.version",
"webauthn4j.version",
"org.apache.kerby.kerby-asn1.version",
]
@ -658,12 +761,12 @@ _keycloakToWildflyProperties = {
# Skip "jmeter.analysis.plugin.version" since Keycloak specific
# Skip "minify.plugin.version" since Keycloak specific
# Skip "osgi.bundle.plugin.version" since Keycloak specific
"wildfly.plugin.version" : "version.org.wildfly.maven.plugins",
"wildfly.plugin.version" : "version.org.wildfly.plugin",
# Skip "nexus.staging.plugin.version" since Keycloak specific
# Skip "frontend.plugin.version" since Keycloak specific
# Skip "docker.maven.plugin.version" since Keycloak specific
# Skip "tomcat7.version", "tomcat8.version", and "tomcat9.version" since Keycloak specific
# Skip "spring-boot15.version", "spring-boot21.version", and "spring-boot22.version" since Keycloak specific
# Skip "spring-boot15.version", "spring-boot21.version", "spring-boot22.version", and "spring-boot23.version" since Keycloak specific
# Skip "webauthn4j.version" since Keycloak specific
# Skip "org.apache.kerby.kerby-asn1.version" since Keycloak specific
}
@ -725,7 +828,7 @@ _wildflyCoreProperties = [
"junit.version",
]
def updateMainKeycloakPomFile(wildflyPomFile, wildflyCorePomFile):
def performMainKeycloakPomFileUpdateTask(wildflyPomFile, wildflyCorePomFile, forceUpdates = False):
"""
Synchronize the versions of artifacts listed as properties in the main
Keycloak pom.xml file with their counterparts taken from 'wildflyPomFile'
@ -764,7 +867,10 @@ def updateMainKeycloakPomFile(wildflyPomFile, wildflyCorePomFile):
"Not updating version of '%s' from '%s' to '%s' since the artifact is excluded!" %
(keycloakElemName, keycloakElem[0].text, wildflyElem[0].text)
)
elif parseVersion(wildflyElem[0].text) > parseVersion(keycloakElem[0].text):
elif (
forceUpdates or
compareMavenVersions(wildflyElem[0].text, keycloakElem[0].text) > 0
):
stepLogger.debug(
"Updating version of '%s' artifact to '%s'. Current '%s' version is less than that." %
(keycloakElemName, wildflyElem[0].text, keycloakElem[0].text)
@ -782,7 +888,7 @@ def updateMainKeycloakPomFile(wildflyPomFile, wildflyCorePomFile):
)
lxml.etree.ElementTree(keycloakXmlTreeRoot).write(mainKeycloakPomPath, encoding = "UTF-8", pretty_print = True, xml_declaration = True)
stepLogger.info("Done syncing artifact version changes to: '%s'" % mainKeycloakPomPath.replace(getKeycloakGitRepositoryRoot(), '.'))
stepLogger.info("Done syncing artifact version changes to: '%s'!" % mainKeycloakPomPath.replace(getKeycloakGitRepositoryRoot(), '.'))
stepLogger.debug("Wrote updated main Keycloak pom.xml file to: '%s'" % mainKeycloakPomPath)
#
@ -790,7 +896,7 @@ def updateMainKeycloakPomFile(wildflyPomFile, wildflyCorePomFile):
# adapter license files related with a Wildfly upgrade
#
def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile):
def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile, forceLicenseFileUpdates = False):
"""
Save GAV dictionary 'gavDictionary' back to XML 'licenseFile'.
"""
@ -812,7 +918,8 @@ def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile)
groupIdElem, artifactIdElem, versionElem = gavEntry[0], gavEntry[1], gavEntry[2]
_logErrorAndExitIf(
"Failed to update '%s' XML dependency!" % gavEntry,
groupIdElem is None or artifactIdElem is None or versionElem is None
groupIdElem is None or artifactIdElem is None or versionElem is None,
logger = stepLogger
)
currentArtifactVersion = versionElem.text
gavDictKey = groupIdElem.text + _gav_delimiter + artifactIdElem.text
@ -820,11 +927,17 @@ def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile)
# Value of the artifact version might be a child dictionary again.
# Get numeric artifact version first
expectedArtifactVersion = getNumericArtifactVersion(gavDictionary, gavDictKey)
# Update the version of artifact if version from GAV dictionary is higher
if expectedArtifactVersion and parseVersion(expectedArtifactVersion) > parseVersion(versionElem.text):
if (
expectedArtifactVersion != currentArtifactVersion and
forceLicenseFileUpdates or
compareMavenVersions(expectedArtifactVersion, versionElem.text) > 0
):
updatingArtifactVersionMessage = (
"Updating the version of '%s, %s' artifact in license file from: '%s' to: '%s'" %
(groupIdElem.text, artifactIdElem.text, currentArtifactVersion, expectedArtifactVersion)
"Updating the version of '%s, %s' artifact in the '%s' license file from: '%s' to: '%s'" %
(groupIdElem.text, artifactIdElem.text, licenseFile, currentArtifactVersion, expectedArtifactVersion)
)
stepLogger.debug(updatingArtifactVersionMessage)
versionElem.text = expectedArtifactVersion
@ -836,13 +949,17 @@ def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile)
currentFilename = filename
currentFileName = currentFilename.replace(repositoryRoot, '').rstrip()
newFilename = currentFilename.replace(currentArtifactVersion, expectedArtifactVersion)
# Delete & recreate the TXT file if it previously existed (be idempotent)
if os.path.isfile(os.path.join(root, newFilename)):
os.remove(os.path.join(root, newFilename))
check_call(['git', 'mv', "%s" % os.path.join(root, currentFilename), "%s" % os.path.join(root, newFilename)], cwd = repositoryRoot)
# Subtask: Update artifact version in license URL to the expected one
dependencyElem = groupIdElem.getparent()
urlElements = getElementsByXPath(dependencyElem, './licenses/license/url', nameSpace)
_logErrorAndExitIf(
"Failed to retrieve <url> element of the '%s' artifact!" % gavDictKey,
len(urlElements) != 1
len(urlElements) != 1,
logger = stepLogger
)
urlElem = urlElements[0]
# Strip the '.redhat-\d+' suffix from artifact versions when processing RH-SSO adapters
@ -870,7 +987,8 @@ def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile)
else:
_logErrorAndExitIf(
"Unable to locate previous '%s' artifact version in the URL!" % gavDictKey,
True
True,
logger = stepLogger
)
else:
try:
@ -885,7 +1003,8 @@ def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile)
else:
_logErrorAndExitIf(
"Unable to locate previous '%s' artifact version in the URL!" % gavDictKey,
True
True,
logger = stepLogger
)
except AttributeError:
# Ignore generic URLs not containing 'major.minor.micro' information of this specific artifact
@ -904,14 +1023,14 @@ def updateAdapterLicenseFile(gavDictionary, xPathPrefix, nameSpace, licenseFile)
lxml.etree.ElementTree(licenseFileXmlTreeRoot).write(licenseFile, encoding = "UTF-8", pretty_print = True, xml_declaration = True)
relativeLicenseFilePath = licenseFile.replace(getKeycloakGitRepositoryRoot(), '.')
stepLogger.info("Done syncing artifact version changes to: '%s'" % relativeLicenseFilePath)
stepLogger.info("Done syncing artifact version changes to: '%s'!" % relativeLicenseFilePath)
stepLogger.debug("Wrote updated license file to: '%s'" % licenseFile)
#
# Routines performing particular tasks within a Wildfly upgrade
#
def performKeycloakAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile):
def performKeycloakAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile, forceUpdates = False):
"""
Update artifacts versions of selected dependencies utilized by various
Keycloak adapter license XML files. Also update the location of the
@ -944,15 +1063,16 @@ def performKeycloakAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomF
taskLogger.info(taskLabel)
isTaskLogged = True
for filename in files:
if re.search(r'distribution.*%s.*licenses.xml' % productName.lower(), os.path.join(root, filename)):
if re.search(r'distribution.*/src/main/resources/licenses/%s/licenses.xml' % productName.lower(), os.path.join(root, filename)):
updateAdapterLicenseFile(
unitedGavDictionary,
xPathPrefix = '/licenseSummary/dependencies/dependency',
nameSpace = {},
licenseFile = os.path.join(root, filename)
licenseFile = os.path.join(root, filename),
forceLicenseFileUpdates = forceUpdates
)
def performRhssoAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile):
def performRhssoAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile, forceUpdates = False):
"""
Update artifacts versions of selected dependencies utilized by various
RH-SSO adapter license XML files. Also update the location of the
@ -988,10 +1108,270 @@ def performRhssoAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile
taskLogger.info(taskLabel)
isTaskLogged = True
for filename in files:
if re.search(r'distribution.*%s.*licenses.xml' % productName.lower(), os.path.join(root, filename)):
if re.search(r'distribution.*/src/main/resources/licenses/%s/licenses.xml' % productName.lower(), os.path.join(root, filename)):
updateAdapterLicenseFile(
gavDictionary,
xPathPrefix = '/licenseSummary/dependencies/dependency',
nameSpace = {},
licenseFile = os.path.join(root, filename)
licenseFile = os.path.join(root, filename),
forceLicenseFileUpdates = forceUpdates
)
def performDeprecatedWildflyTestingModuleUpdateTask(forceUpdates = False):
"""
Update the properties of the deprecated Wildfly testing module present in
the Arquillian testsuite if necessary. The properties are needed to be
updated if and only if the Wildfly and Wildfly Core versions in the main
Keycloak pom.xml file from the local Keycloak git clone are higher than
Widfly and Wildfly Core versions in the main Keycloak pom.xml file of the
master branch of official Keycloak GitHub repository (IOW if and only the
main Keycloak pom.xml file in the local repository got already updated with
new Wildfly and Wildfly Core artifact versions from the new tag)
"""
# Prepare / hold the expected future values of the properties of the
# deprecated Wildfly testing module present in Arquillian testsuite
deprecatedWildflyModuleProperties = {}
deprecatedWildflyModuleProperties['wildfly.deprecated.version'] = getPomPropertyFromRemoteXml(
_keycloak_github_master_main_pom_base_url,
'wildfly.version',
errorMessage = "Unable to locate 'wildfly.version' property element in the remote XML file!",
expectedElementsCount = 1
)[0].text
deprecatedWildflyModuleProperties['wildfly.deprecated.wildfly.core.version'] = getPomPropertyFromRemoteXml(
_keycloak_github_master_main_pom_base_url,
'wildfly.core.version',
errorMessage = "Unable to locate 'wildfly.core.version' property element in the remote XML file!",
expectedElementsCount = 1
)[0].text
deprecatedWildflyModuleProperties['wildfly.deprecated.arquillian.wildfly.container'] = getPomPropertyFromRemoteXml(
_wildfly_github_tag_main_pom_base_url % deprecatedWildflyModuleProperties['wildfly.deprecated.version'],
'version.org.wildfly.arquillian',
errorMessage = "Unable to locate 'version.org.wildfly.arquillian' property element in the remote XML file!",
expectedElementsCount = 1
)[0].text
taskLogger = getTaskLogger('Update Deprecated Wildfly Testing Module')
taskLogger.info('Updating properties of the deprecated Wildfly testing module...')
stepLogger = getStepLogger()
# Absolute path to main Keycloak pom.xml within the local repo
mainKeycloakPomPath = getKeycloakGitRepositoryRoot() + "/pom.xml"
mainKeycloakPomXmlRoot = getXmlRoot(mainKeycloakPomPath)
# Absolute path to pom.xml file of the Arquillian testsuite within the local repo
arqTestSuitePomPath = getKeycloakGitRepositoryRoot() + "/testsuite/integration-arquillian/pom.xml"
arqTestSuitePomXmlRoot = getXmlRoot(arqTestSuitePomPath)
# Determine the current value of the 'wildfly.version' property element
# from the main pom.xml file of the local Keycloak git repository clone
currentLocalWildflyVersionElem = getPomProperty(mainKeycloakPomXmlRoot, 'wildfly.version')
_logErrorAndExitIf(
"Unable to determine the value of the 'wildfly.version' property element in the main Keycloak pom.xml file!",
len(currentLocalWildflyVersionElem) != 1,
logger = stepLogger
)
currentLocalWildflyVersion = currentLocalWildflyVersionElem[0].text
# Determine the current value of the 'wildfly.core.version' property
# element from the main pom.xml file of the local Keycloak git repository
# clone
currentLocalWildflyCoreVersionElem = getPomProperty(mainKeycloakPomXmlRoot, 'wildfly.core.version')
_logErrorAndExitIf(
"Unable to determine the value of the 'wildfly.core.version' property element in the main Keycloak pom.xml file!",
len(currentLocalWildflyCoreVersionElem) != 1,
logger = stepLogger
)
currentLocalWildflyCoreVersion = currentLocalWildflyCoreVersionElem[0].text
# Update the properties of the deprecated Wildfly testing module present
# in the Arquillian testsuite if the local Wildfly and Wildfly Core version
# is higher than their counterparts currently present in the master branch
# of the Keycloak GitHub repository (IOW only if main Keycloak's pom.xml
# got previously already updated with artifact versions from the new
# Wildfly tag)
if (
forceUpdates or
compareMavenVersions(currentLocalWildflyVersion, deprecatedWildflyModuleProperties['wildfly.deprecated.version']) > 0 and
compareMavenVersions(currentLocalWildflyCoreVersion, deprecatedWildflyModuleProperties['wildfly.deprecated.wildfly.core.version']) > 0
):
for deprecatedProperty in deprecatedWildflyModuleProperties.keys():
arqTestSuitePropertyElem = getPomProperty(arqTestSuitePomXmlRoot, deprecatedProperty)
_logErrorAndExitIf(
"Unable to locate the '%s' element in the pom.xml file of the Arquillian testsuite!",
len(arqTestSuitePropertyElem) != 1,
logger = stepLogger
)
stepLogger.debug(
"Updating value of the '%s' property of the deprecated Wildfly module to '%s'" %
(deprecatedProperty, deprecatedWildflyModuleProperties[deprecatedProperty])
)
arqTestSuitePropertyElem[0].text = deprecatedWildflyModuleProperties[deprecatedProperty]
else:
updateNotNecessaryMessage = (
"Not updating the values of the properties of the deprecated Wildfly testing module!"
"\n\t\t Versions of Wildfly and Wildfly Core artifacts found in the main pom.xml file"
"\n\t\t of this repository are equal, or lower when compared to their respective versions"
"\n\t\t currently present in the 'master' branch of the upstream GitHub Keycloak repository."
"\n\t\t Update is not needed."
)
stepLogger.debug(_empty_string.join(updateNotNecessaryMessage))
lxml.etree.ElementTree(arqTestSuitePomXmlRoot).write(arqTestSuitePomPath, encoding = "UTF-8", pretty_print = True, xml_declaration = True)
stepLogger.info('Done syncing necessary changes to the deprecated Wildfly testing module!')
def performJbossParentVersionUpdateTask(wildflyTag, wildflyPomFile, wildflyCorePomFile, forceUpdates = False):
taskLogger = getTaskLogger('Update Version of jboss-parent')
taskLogger.info("Checking if the 'jboss-parent' version needs to be updated...")
stepLogger = getStepLogger()
# Absolute path to main Keycloak pom.xml within the local repo
mainKeycloakPomPath = getKeycloakGitRepositoryRoot() + "/pom.xml"
mainKeycloakPomXmlRoot = getXmlRoot(mainKeycloakPomPath)
# Absolute path to the Keycloak's 'boms/pom.xml' location within the local repo
keycloakBomsPomPath = getKeycloakGitRepositoryRoot() + "/boms/pom.xml"
keycloakBomsPomXmlRoot = getXmlRoot(keycloakBomsPomPath)
# Retrieve the current versions of the 'jboss-parent' from the:
jbossParentVersionElems = {}
# Main pom.xml file of the Wildfly repository
jbossParentVersionElems['from.main.wildfly.pom'] = getElementsByXPath(getXmlRoot(wildflyPomFile), '/pom:project/pom:parent/pom:version')
# Main pom.xml file of the Wildfly Core repository
jbossParentVersionElems['from.main.wildfly.core.pom'] = getElementsByXPath(getXmlRoot(wildflyCorePomFile), '/pom:project/pom:parent/pom:version')
# Main pom.xml file of the local Keycloak repository
jbossParentVersionElems['from.main.keycloak.pom'] = getElementsByXPath(mainKeycloakPomXmlRoot, '/pom:project/pom:parent/pom:version')
# The boms/pom.xml file of the local Keycloak repository
jbossParentVersionElems['from.keycloak.boms.pom'] = getElementsByXPath(keycloakBomsPomXmlRoot, '/pom:project/pom:parent/pom:version')
# Sanity check if jboss-parent elements were retrieved correctly from all of the four files
# (in each case there should be exactly one 'jboss-parent' element present in the pom.xml)
for key, value in jbossParentVersionElems.items():
location = (
key
.replace('boms.pom', "'boms/pom'")
.replace('keycloak', 'Keycloak')
.replace('wildfly', 'Wildfly')
.replace('core', 'Core')
.replace('from', 'from the')
.replace('pom', 'pom.xml')
.replace('.', ' ')
)
_logErrorAndExitIf(
"Unable to determine the version of the 'jboss-parent' element %s file!" % location,
len(value) != 1,
logger = stepLogger
)
# Turn list containing one XML element into just the XML element itself
jbossParentVersionElems[key] = value[0]
# Synchronize the jboss-parent version in both the main Keycloak pom.xml file and in the 'boms/pom.xml' file
# (if their version differs from the current versions used by Wildfly / Wildfly Core)
if (
forceUpdates or
jbossParentVersionElems['from.main.wildfly.pom'].text == jbossParentVersionElems['from.main.wildfly.core.pom'].text and
jbossParentVersionElems['from.main.wildfly.pom'].text != jbossParentVersionElems['from.main.keycloak.pom'].text or
jbossParentVersionElems['from.main.wildfly.pom'].text != jbossParentVersionElems['from.keycloak.boms.pom'].text
):
updatedJBossParentVersion = jbossParentVersionElems['from.main.wildfly.pom'].text
stepLogger.info("Updating version of 'jboss-parent' in the main Keycloak pom.xml file...")
jbossParentVersionElems['from.main.keycloak.pom'].text = updatedJBossParentVersion
lxml.etree.ElementTree(mainKeycloakPomXmlRoot).write(mainKeycloakPomPath, encoding = "UTF-8", pretty_print = True, xml_declaration = True)
stepLogger.info("'jboss-parent' version updated to '%s' to match the version used by Wildfly '%s'!" % (updatedJBossParentVersion, wildflyTag))
stepLogger.info("Updating version of 'jboss-parent' in the Keycloak's 'boms/pom.xml' file...")
jbossParentVersionElems['from.keycloak.boms.pom'].text = updatedJBossParentVersion
lxml.etree.ElementTree(keycloakBomsPomXmlRoot).write(keycloakBomsPomPath, encoding = "UTF-8", pretty_print = True, xml_declaration = True)
stepLogger.info("'jboss-parent' version updated to '%s' to match the version used by Wildfly '%s'!" % (updatedJBossParentVersion, wildflyTag))
# No update necessary ('jboss-parent' versions are already equal)
else:
jbossParentVersionUpdateNotNecessaryMsg = (
"Update of the 'jboss-parent' version is not necessary!",
"\n\t\tCurrent '%s' version used by Keycloak already matches the current '%s' version used by Wildfly '%s'." %
(jbossParentVersionElems['from.main.keycloak.pom'].text, jbossParentVersionElems['from.main.wildfly.pom'].text, wildflyTag)
)
stepLogger.info(_empty_string.join(jbossParentVersionUpdateNotNecessaryMsg))
def synchronizeInfinispanSubsystemXmlNamespaceWithWildfly(wildflyTag):
"""
Update the XML namespace of the 'subsystem' element of the Keycloak
Infinispan subsystem template with its current value as used by Wildfly.
"""
taskLogger = getTaskLogger("Update 'urn:jboss:domain:infinispan:*' version")
taskLogger.info('Synchronizing XML namespace of Infinispan subsystem from Wildfly to Keycloak...')
stepLogger = getStepLogger()
wildflyInfinispanSubsystemElementErrorMessage = (
"Unable to locate 'subsystem' XML element in the remote XML file!"
)
# Retrieve 'subsystem' element from the Wildfly's Infinispan
# subsystem-template XML file
wildflyInfinispanSubsystemElement = list(filter(
lambda elem: 'subsystem' in elem.tag,
getElementsByXPathFromRemoteXml(
_wildfly_github_tag_ispn_subtempl_base_url % wildflyTag,
xPath = '/config/*',
nameSpace = {}
)
))
# Sanity check
_logErrorAndExitIf(
wildflyInfinispanSubsystemElementErrorMessage,
len(wildflyInfinispanSubsystemElement) != 1
)
# Retrieve namespace value of that 'subsystem' element
wildflyInfinispanSubsystemElementNamespace = (
lxml.etree.QName(wildflyInfinispanSubsystemElement[0]).namespace
)
# Absolute path to the Infinispan subsystem template XML file
# within local Keycloak git repository
keycloakInfinispanSubsystemTemplateXmlPath = (
getKeycloakGitRepositoryRoot() +
'/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml'
)
# XML root of the Keycloak Infinispan subsystem template XML file
keycloakInfinispanSubsystemTemplateXmlRoot = getXmlRoot(
keycloakInfinispanSubsystemTemplateXmlPath
)
keycloakInfinispanSubsystemElementErrorMessage = (
"Unable to locate 'subsystem' XML element in the local XML file!",
)
# Retrieve 'subsystem' element from the Keycloak's Infinispan
# subsystem-template XML file
keycloakInfinispanSubsystemElement = list(filter(
lambda elem: 'subsystem' in elem.tag,
getElementsByXPath(
keycloakInfinispanSubsystemTemplateXmlRoot,
xPath = '/config/*',
nameSpace = {}
)
))
# Sanity check
_logErrorAndExitIf(
keycloakInfinispanSubsystemElementErrorMessage,
len(keycloakInfinispanSubsystemElement) != 1
)
# Update namespace of Keycloak's Infinispan 'subsystem' element in
# subsystem-template XML file to match namespace value from Wildfly
keycloakInfinispanSubsystemElementParent = keycloakInfinispanSubsystemElement[0].getparent()
keycloakInfinispanSubsystemElementIndex = keycloakInfinispanSubsystemElementParent.index(
keycloakInfinispanSubsystemElement[0]
)
keycloakInfinispanSubsystemElementParent.remove(keycloakInfinispanSubsystemElement[0])
keycloakInfinispanSubsystemElementParent.insert(
keycloakInfinispanSubsystemElementIndex,
wildflyInfinispanSubsystemElement[0]
)
# Write the changes back to Keycloak Infinispan subsystem-template XML file
lxml.etree.ElementTree(keycloakInfinispanSubsystemTemplateXmlRoot).write(
keycloakInfinispanSubsystemTemplateXmlPath,
encoding = "UTF-8",
pretty_print = True,
xml_declaration = True
)
stepLogger.info(
"Updated XML namespace of the Keycloak's Infinispan subsystem to '%s'" %
lxml.etree.QName(wildflyInfinispanSubsystemElement[0]).namespace
)

View file

@ -0,0 +1,10 @@
# fabric8-analytics-version-comparator/f8a\_version\_comparator
Python module/library implementing generic Maven version comparison:
https://github.com/apache/maven/blob/master/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
The "f8a\_version\_comparator" Python module implementation was taken
from "fabric8-analytics/fabric8-analytics-version-comparator" repository:
https://github.com/fabric8-analytics/fabric8-analytics-version-comparator

View file

@ -0,0 +1,28 @@
# Copyright © 2018 Red Hat Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Geetika Batra <gbatra@redhat.com>
#
"""Initialize Module."""
__all__ = [
"base",
"comparable_version",
"item_object",
]
from . import base
from . import comparable_version
from . import item_object

View file

@ -0,0 +1,28 @@
# Copyright © 2018 Red Hat Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Geetika Batra <gbatra@redhat.com>
#
"""Item class acting as base class for various item types."""
from abc import ABCMeta, abstractmethod
class Item(metaclass=ABCMeta):
"""Base class for maven version comparator tasks."""
@abstractmethod
def compare_to(self, _item):
"""Compare two maven versions."""

View file

@ -0,0 +1,213 @@
# Copyright © 2018 Red Hat Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Geetika Batra <gbatra@redhat.com>
#
"""Module to implement Comparable Version class."""
import typing
from .item_object import IntegerItem
from .item_object import StringItem
from .item_object import ListItem
class ComparableVersion:
"""Class for Comparable Version."""
def __init__(self, version: str):
"""Initialize comparable version class.
:version: Version supplied as a string
"""
if not isinstance(version, str):
raise TypeError(
"Invalid type {got!r} of argument `version`, expected {expected!r}".format(
got=type(version),
expected=str
))
self.version = version
self.items = self.parse_version()
def __repr__(self):
"""Return representation of ComparableVersion object."""
return "{cls!s}(version={version!r})".format(
cls=self.__class__.__name__,
version=self.version
)
def __str__(self):
"""Return version string held by ComparableVersion object."""
return "{version!s}".format(
version=self.version
)
def __eq__(self, other):
"""Compare ComparableVersion objects for equality.
This rich comparison implies whether self == other
"""
# don't call compare_to(None)
if other is None:
return False
return self.compare_to(other) == 0
def __ne__(self, other):
"""Compare ComparableVersion objects for equality.
This rich comparison implies whether self != other
"""
# don't call compare_to(None)
if other is None:
return True
return self.compare_to(other) != 0
def __lt__(self, other):
"""Compare ComparableVersion objects.
This rich comparison implies whether self < other
"""
# don't call compare_to(None)
if other is None:
return False
return self.compare_to(other) == -1
def __le__(self, other):
"""Compare ComparableVersion objects.
This rich comparison implies whether self <= other
"""
# don't call compare_to(None)
if other is None:
return False
return self.compare_to(other) <= 0
def __gt__(self, other):
"""Compare ComparableVersion objects.
This rich comparison implies whether self > other
"""
# don't call compare_to(None)
if other is None:
return True
return self.compare_to(other) == 1
def __ge__(self, other):
"""Compare ComparableVersion objects.
This rich comparison implies whether self >= other
"""
# don't call compare_to(None)
if other is None:
return True
return self.compare_to(other) >= 0
def parse_version(self):
"""Parse version."""
# TODO: reduce cyclomatic complexity
ref_list = ListItem()
items = ref_list
parse_stack = list()
version = self.version.lower()
parse_stack.append(ref_list)
_is_digit = False
_start_index = 0
for _ch in range(0, len(version)):
ver_char = version[_ch]
if ver_char == ".":
if _ch == _start_index:
ref_list.add_item(IntegerItem(0))
else:
ref_list.add_item(self.parse_item(_is_digit, version[_start_index: _ch]))
_start_index = _ch + 1
elif ver_char == "-":
if _ch == _start_index:
ref_list.add_item(IntegerItem(0))
else:
ref_list.add_item(self.parse_item(_is_digit, version[_start_index: _ch]))
_start_index = _ch + 1
temp = ListItem()
ref_list.add_item(temp)
ref_list = temp
parse_stack.append(ref_list)
elif ver_char.isdigit():
if not _is_digit and _ch > _start_index:
ref_list.add_item(StringItem(version[_start_index: _ch], True))
_start_index = _ch
temp = ListItem()
ref_list.add_item(temp)
ref_list = temp
parse_stack.append(ref_list)
_is_digit = True
else:
if _is_digit and _ch > _start_index:
ref_list.add_item(self.parse_item(True, version[_start_index:_ch]))
_start_index = _ch
temp = ListItem()
ref_list.add_item(temp)
ref_list = temp
parse_stack.append(ref_list)
_is_digit = False
if len(version) > _start_index:
ref_list.add_item(self.parse_item(_is_digit, version[_start_index:]))
while parse_stack:
ref_list = parse_stack.pop()
ref_list.normalize()
return items
@staticmethod
def parse_item(_is_digit, buf):
"""Wrap items in version in respective object class."""
# TODO: make this function static (it does not need 'self')
if _is_digit:
return IntegerItem(buf)
return StringItem(buf, False)
def compare_to(self, obj: typing.Union["ComparableVersion", str]):
"""Compare two ComparableVersion objects."""
if isinstance(obj, ComparableVersion):
# compare two objects of the same type
cmp_result = self.items.compare_to(obj.items)
elif isinstance(obj, str):
# compare against string
cmp_result = self.items.compare_to(ComparableVersion(obj).items)
else:
raise TypeError(
"Invalid type {got!r} of argument `obj`, expected <{expected}>".format(
got=type(obj),
expected=typing.Union["ComparableVersion", str]
))
return cmp_result

View file

@ -0,0 +1,204 @@
# Copyright © 2018 Red Hat Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Geetika Batra <gbatra@redhat.com>
#
"""Module to implement methods item types."""
from .base import Item
# TODO: setup logging
class IntegerItem(Item):
"""Integer Item class for maven version comparator tasks."""
def __init__(self, str_version):
"""Initialize integer from string value of version.
:str_version: part of version supplied as string
"""
self.value = int(str_version)
def int_cmp(self, cmp_value):
"""Compare two integers."""
if self.value.__lt__(cmp_value):
return -1
if self.value.__gt__(cmp_value):
return 1
return 0
def compare_to(self, item):
"""Compare two maven versions."""
if item is None:
return 0 if self.value == 0 else 1
if isinstance(item, IntegerItem):
return self.int_cmp(item.value) # check if this value thing works
if isinstance(item, StringItem):
return 1
if isinstance(item, ListItem):
return 1
else:
raise ValueError("invalid item" + str(type(item)))
def to_string(self):
"""Return string value of version."""
return str(self.value)
def __str__(self):
"""Return string value of version - Pythonish variant."""
return str(self.value)
class StringItem(Item):
"""String Item class for maven version comparator tasks."""
def __init__(self, str_version, followed_by_digit):
"""Initialize string value of version.
:str_value: part of version supplied as string
:followed_by_digit: True if str_version is followed by digit
"""
self.qualifiers = ["alpha", "beta", "milestone", "rc", "snapshot", "", "sp"]
self.aliases = {
"ga": "",
"final": "",
"cr": "rc"
}
self.release_version_index = str(self.qualifiers.index(""))
self._decode_char_versions(str_version, followed_by_digit)
def _decode_char_versions(self, value, followed_by_digit):
"""Decode short forms of versions."""
if followed_by_digit and len(value) == 1:
if value.startswith("a"):
value = "alpha"
elif value.startswith("b"):
value = "beta"
elif value.startswith("m"):
value = "milestone"
self.value = self.aliases.get(value, value)
def comparable_qualifier(self, qualifier):
"""Get qualifier that is comparable."""
q_index = None
if qualifier in self.qualifiers:
q_index = self.qualifiers.index(qualifier)
q_index_not_found = str(len(self.qualifiers)) + "-" + qualifier
return str(q_index) if q_index is not None else q_index_not_found
def str_cmp(self, val1, val2):
"""Compare two strings."""
if val1.__lt__(val2):
return -1
if val1.__gt__(val2):
return 1
return 0
def compare_to(self, item):
"""Compare two maven versions."""
if item is None:
temp = self.str_cmp(self.comparable_qualifier(self.value), self.release_version_index)
return temp
if isinstance(item, IntegerItem):
return -1
if isinstance(item, StringItem):
return self.str_cmp(
self.comparable_qualifier(
self.value), self.comparable_qualifier(
item.value))
if isinstance(item, ListItem):
return -1
else:
raise ValueError("invalid item" + str(type(item)))
def to_string(self):
"""Return value in string form."""
return str(self.value)
def __str__(self):
"""Return string value of version - Pythonish variant."""
return str(self.value)
class ListItem(Item):
"""List Item class for maven version comparator tasks."""
def __init__(self):
"""Initialize string value of version."""
self.array_list = list()
def add_item(self, item):
"""Add item to array list."""
self.array_list.append(item)
def get_list(self):
"""Get object list items."""
return self.array_list
def normalize(self):
"""Remove trailing items: 0, "", empty list."""
red_list = [0, None, ""]
i = len(self.array_list) - 1
while i >= 0:
last_item = self.array_list[i]
if not isinstance(last_item, ListItem):
if last_item.value in red_list:
self.array_list.pop(i)
else:
break
i = i - 1
def compare_to(self, item):
"""Compare two maven versions."""
# TODO: reduce cyclomatic complexity
if item is None:
if len(self.array_list) == 0:
return 0
first = self.array_list[0]
return first.compare_to(None)
if isinstance(item, IntegerItem):
return -1
if isinstance(item, StringItem):
return 1
if isinstance(item, ListItem):
left_iter = iter(self.array_list)
right_iter = iter(item.get_list())
while True:
l_obj = next(left_iter, None)
r_obj = next(right_iter, None)
if l_obj is None and r_obj is None:
break
result = 0
if l_obj is None:
if r_obj is not None:
result = -1 * r_obj.compare_to(l_obj)
else:
result = l_obj.compare_to(r_obj)
if result != 0:
return result
return 0
else:
raise ValueError("invalid item" + str(type(item)))

View file

@ -17,52 +17,121 @@
# * limitations under the License.
# *
# *
#
# Purpose: Update various necessary bits of Keycloak to align with the specified Wildfly tag. Perform this by:
#
# * Incrementing the jboss-parent element version if necessary,
# * Updating versions of artifacts shared with Wildfly and Wildfly Core in main Keycloak pom.xml file,
# * Updating versions of artifacts shared with Wildfly and Wildfly Core utilized by Keycloak adapters
#
# Usage: Run as, e.g.:
# ./upgrade-keycloak-to-wildfly-tag.py 20.0.0.Final
#
# Or call the script without arguments to get the further help
import os, sys
import click, logging, os, sys
import wildfly.upgrade as wu
import lib.wildfly.upgrade as wu
def usage():
print("Run as: \n\t%s Wildfly.Tag.To.Upgrade.To \ne.g.:\n\t%s 20.0.0.Final\n" % (sys.argv[0], sys.argv[0]))
CONTEXT_SETTINGS = dict(help_option_names = ['-h', '--help'])
FORCE_OPTION_HELP = """
Force elements / files updates.
if __name__ == '__main__':
In common mode of operation (without the "-f" or "--force" options) the
script upgrades the version of the Keycloak characteristic in question
(POM property, dependency, or some other XML element shared with Wildfly
application server) ONLY if the new version is HIGHER than the version of
the corresponding element currently present in the local copy of the
Keycloak repository, the script is operating on.
if len(sys.argv) != 2:
usage()
sys.exit(1)
The -f, --force options instruct the script to allow an upgrade to replace
newer version of a particular Keycloak characteristic with an older one.
Useful to perform e.g. Keycloak downgrades to previous Wildfly versions.
"""
wildflyTag = wu.isWellFormedWildflyTag(sys.argv[1])
RHSSO_ADAPTERS_OPTION_HELP = """
Update artifacts versions of selected dependencies utilized by various
RH-SSO adapter license XML files. Also update the location of the
corresponding license text files within the repository so their names
reflect the updated artifacts versions.
"""
@click.command(context_settings=CONTEXT_SETTINGS)
@click.argument('tag', required = True, type=click.STRING)
@click.option('-f', '--force', help=FORCE_OPTION_HELP, is_flag=True)
@click.option('-r', '--update-rh-sso-adapters', help=RHSSO_ADAPTERS_OPTION_HELP, is_flag=True)
@click.option('-v', '--verbose', help='Enable verbose output.', is_flag=True)
@click.version_option(prog_name=sys.argv[0], version=wu.__version__)
def processParameters(tag, verbose, force, update_rh_sso_adapters):
"""
NAME
upgrade-keycloak-to-wildfly-tag.py - Rebase Keycloak on top of the
specified Wildfly tag (release)
DESCRIPTION
Update the versions of various Keycloak characteristics (versions of
POM properties, adapter dependencies, and other attributes actually
binding the Keycloak POM build configuration to the particular Wildfly
tag) to their corresponding values as used by the Wildfly application
server of version matching the tag / release, passed to the script as
argument.
EXAMPLES
Upgrade Keycloak to Wildfly 20 (using "20.0.1.Final" Wildfly tag):
$ python upgrade-keycloak-to-wildfly-tag.py 20.0.1.Final
Downgrade Keycloak to Wildfly 16 (using "16.0.0.Final" Wildfly tag,
script verbose mode to display the details about elements being
updated, and force option to perform the actual downgrade):
$ python upgrade-keycloak-to-wildfly-tag.py -v -f 16.0.0.Final
"""
# Set loglevel to debug if '-v' or '--verbose' option was specified
wu.__loglevel__ = logging.DEBUG if verbose else logging.INFO
upgradeKeycloakToWildflyTag(tag, forceUpdates = force, ssoAdapters = update_rh_sso_adapters)
def upgradeKeycloakToWildflyTag(tag, forceUpdates = False, ssoAdapters = False):
wildflyTag = wu.isWellFormedWildflyTag(tag)
wildflyPomBaseUrl = "https://github.com/wildfly/wildfly/raw/%s/pom.xml" % wildflyTag
wu.getModuleLogger().info("Retrieving Wildfly's pom.xml for tag: %s" % wildflyTag)
taskLogger = wu.getTaskLogger("Rebase Keycloak on top of Wildfly '%s'" % wildflyTag)
taskLogger.info("Retrieving Wildfly's pom.xml for tag: %s" % wildflyTag)
wildflyPomFile = wu.saveUrlToNamedTemporaryFile(wildflyPomBaseUrl)
wildflyPomXmlRoot = wu.getXmlRoot(wildflyPomFile)
wildflyCoreTag = wu.isWellFormedWildflyTag( wu.getPomProperty(wildflyPomXmlRoot, "version.org.wildfly.core")[0].text )
wildflyCorePomBaseUrl = "https://github.com/wildfly/wildfly-core/raw/%s/pom.xml" % wildflyCoreTag
wu.getModuleLogger().info("Retrieving Wildfly-Core pom.xml for tag: %s" % wildflyCoreTag)
taskLogger.info("Retrieving Wildfly-Core pom.xml for tag: %s" % wildflyCoreTag)
wildflyCorePomFile = wu.saveUrlToNamedTemporaryFile(wildflyCorePomBaseUrl)
if wildflyPomFile != None and wildflyCorePomFile != None:
# Subtask - Update main Keycloak pom.xml file
wu.updateMainKeycloakPomFile(wildflyPomFile, wildflyCorePomFile)
wu.performMainKeycloakPomFileUpdateTask(wildflyPomFile, wildflyCorePomFile, forceUpdates)
# Subtask - Update Keycloak adapters
wu.performKeycloakAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile)
wu.performKeycloakAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile, forceUpdates)
if ssoAdapters:
# Subtask - Update RH-SSO adapters
wu.performRhssoAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile)
wu.performRhssoAdapterLicenseFilesUpdateTask(wildflyPomFile, wildflyCorePomFile, forceUpdates)
else:
skipRhSsoAdapterUpdatesMessage = (
"Skipping RH-SSO adapters updates since their changes weren't requested!",
"\n\tRerun the script with '-r' or '--update-rh-sso-adapters' option to request them."
)
taskLogger.warning(wu._empty_string.join(skipRhSsoAdapterUpdatesMessage))
# Subtask - Update properties of the deprecated Wildfly testing module if necessary
wu.performDeprecatedWildflyTestingModuleUpdateTask(forceUpdates)
# Subtask - Update version of jboss-parent if necessary
wu.performJbossParentVersionUpdateTask(wildflyTag, wildflyPomFile, wildflyCorePomFile, forceUpdates)
# Subtask - Synchronize the XML namespace of the 'subsystem' element of the Keycloak
# Infinispan subsystem template with its current value as used by Wildfly
wu.synchronizeInfinispanSubsystemXmlNamespaceWithWildfly(wildflyTag)
for filename in [wildflyPomFile, wildflyCorePomFile]:
os.remove(filename)
rebaseDoneMessage = (
"Done rebasing Keycloak to Wildfly '%s' release!" % wildflyTag,
"\n\tRun 'git status' to list the changed files and 'git diff <path>' to inspect changes done to a specific file."
)
taskLogger.info(wu._empty_string.join(rebaseDoneMessage))
if __name__ == '__main__':
processParameters()

View file

@ -22,7 +22,6 @@ import org.infinispan.client.hotrod.exceptions.HotRodClientException;
import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith;
import org.infinispan.commons.util.concurrent.ConcurrentHashSet;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged;

View file

@ -18,20 +18,20 @@
package org.keycloak.cluster.infinispan;
import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith;
import org.keycloak.models.sessions.infinispan.util.KeycloakMarshallUtil;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith;
import org.infinispan.commons.util.concurrent.ConcurrentHashSet;
import org.keycloak.models.sessions.infinispan.util.KeycloakMarshallUtil;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@ -77,7 +77,7 @@ public class LockEntryPredicate implements Predicate<Map.Entry<String, Serializa
public LockEntryPredicate readObjectVersion1(ObjectInput input) throws IOException, ClassNotFoundException {
return new LockEntryPredicate(
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>())
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, ConcurrentHashMap::newKeySet)
);
}
}

View file

@ -178,20 +178,17 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
boolean clustered = config.getBoolean("clustered", false);
boolean async = config.getBoolean("async", false);
boolean allowDuplicateJMXDomains = config.getBoolean("allowDuplicateJMXDomains", true);
this.topologyInfo = new TopologyInfo(cacheManager, config, true);
if (clustered) {
String jgroupsUdpMcastAddr = config.get("jgroupsUdpMcastAddr", System.getProperty(InfinispanConnectionProvider.JGROUPS_UDP_MCAST_ADDR));
configureTransport(gcb, topologyInfo.getMyNodeName(), topologyInfo.getMySiteName(), jgroupsUdpMcastAddr);
gcb.globalJmxStatistics()
gcb.jmx()
.jmxDomain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + topologyInfo.getMyNodeName());
}
gcb.globalJmxStatistics()
.allowDuplicateDomains(allowDuplicateJMXDomains)
.enable();
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
// For Infinispan 10, we go with the JBoss marshalling.
// TODO: This should be replaced later with the marshalling recommended by infinispan. Probably protostream.
@ -484,7 +481,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
}
transportBuilder.globalJmxStatistics()
transportBuilder.jmx()
.jmxDomain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + nodeName)
.enable();

View file

@ -17,22 +17,21 @@
package org.keycloak.models.sessions.infinispan.entities;
import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith;
import org.keycloak.models.sessions.infinispan.util.KeycloakMarshallUtil;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.sessions.CommonClientSessionModel.ExecutionStatus;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.infinispan.commons.util.concurrent.ConcurrentHashSet;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.sessions.CommonClientSessionModel.ExecutionStatus;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@ -52,7 +51,7 @@ public class AuthenticationSessionEntity implements Serializable {
private Map<String, String> clientNotes;
private Map<String, String> authNotes;
private Set<String> requiredActions = new ConcurrentHashSet<>();
private Set<String> requiredActions = ConcurrentHashMap.newKeySet();
private Map<String, String> userSessionNotes;
public AuthenticationSessionEntity() {
@ -234,14 +233,14 @@ public class AuthenticationSessionEntity implements Serializable {
MarshallUtil.unmarshallString(input), // redirectUri
MarshallUtil.unmarshallString(input), // action
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // clientScopes
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, ConcurrentHashMap::newKeySet), // clientScopes
KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, EXECUTION_STATUS_EXT, size -> new ConcurrentHashMap<>(size)), // executionStatus
MarshallUtil.unmarshallString(input), // protocol
KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashMap<>(size)), // clientNotes
KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashMap<>(size)), // authNotes
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashSet<>()), // requiredActions
KeycloakMarshallUtil.readCollection(input, KeycloakMarshallUtil.STRING_EXT, ConcurrentHashMap::newKeySet), // requiredActions
KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, size -> new ConcurrentHashMap<>(size)) // userSessionNotes
);
}

View file

@ -18,6 +18,7 @@
package org.keycloak.models.sessions.infinispan.remotestore;
import java.io.Serializable;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -74,9 +75,13 @@ public class RemoteCacheSessionsLoader implements SessionLoader<RemoteCacheSessi
protected int getIspnSegmentsCount(RemoteCache remoteCache) {
OperationsFactory operationsFactory = ((RemoteCacheImpl) remoteCache).getOperationsFactory();
Map<SocketAddress, Set<Integer>> segmentsByAddress = operationsFactory.getPrimarySegmentsByAddress();
for (Map.Entry<SocketAddress, Set<Integer>> entry : segmentsByAddress.entrySet()) {
SocketAddress targetAddress = entry.getKey();
// Same like RemoteCloseableIterator.startInternal
IterationStartOperation iterationStartOperation = operationsFactory.newIterationStartOperation(null, null, null, sessionsPerSegment, false, null);
IterationStartOperation iterationStartOperation = operationsFactory.newIterationStartOperation(null, null, null, sessionsPerSegment, false, null, targetAddress);
IterationStartResponse startResponse = await(iterationStartOperation.execute());
try {
@ -90,6 +95,9 @@ public class RemoteCacheSessionsLoader implements SessionLoader<RemoteCacheSessi
startResponse.getChannel().close();
}
}
// Handle the case when primary segments owned by the address are not known
return -1;
}
@Override

View file

@ -19,6 +19,7 @@
package org.keycloak.cluster.infinispan;
import java.awt.print.Book;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -131,9 +132,13 @@ public class JDGPutTest {
protected static int getIspnSegmentsCount(RemoteCache remoteCache) {
OperationsFactory operationsFactory = ((RemoteCacheImpl) remoteCache).getOperationsFactory();
Map<SocketAddress, Set<Integer>> segmentsByAddress = operationsFactory.getPrimarySegmentsByAddress();
for (Map.Entry<SocketAddress, Set<Integer>> entry : segmentsByAddress.entrySet()) {
SocketAddress targetAddress = entry.getKey();
// Same like RemoteCloseableIterator.startInternal
IterationStartOperation iterationStartOperation = operationsFactory.newIterationStartOperation(null, null, null, 64, false, null);
IterationStartOperation iterationStartOperation = operationsFactory.newIterationStartOperation(null, null, null, 64, false, null, targetAddress);
IterationStartResponse startResponse = await(iterationStartOperation.execute());
try {
@ -147,6 +152,9 @@ public class JDGPutTest {
startResponse.getChannel().close();
}
}
// Handle the case when primary segments owned by the address are not known
return -1;
}
// Compute set of ISPN segments into 1 "worker" segment
protected static Set<Integer> getMyIspnSegments(int segment, RemoteCacheSessionsLoaderContext ctx) {

View file

@ -38,31 +38,21 @@ class TestCacheManagerFactory {
<T extends StoreConfigurationBuilder<?, T> & RemoteStoreConfigurationChildBuilder<T>> EmbeddedCacheManager createManager(int threadId, String cacheName, Class<T> builderClass) {
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("jgroups.tcp.port", "53715");
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
gcb = gcb.clusteredDefault();
gcb.transport().clusterName("test-clustering-" + threadId);
// For Infinispan 10, we go with the JBoss marshalling.
// TODO: This should be replaced later with the marshalling recommended by infinispan. Probably protostream.
// See https://infinispan.org/docs/stable/titles/developing/developing.html#marshalling for the details
gcb.serialization().marshaller(new JBossUserMarshaller());
boolean clustered = true;
boolean async = false;
boolean allowDuplicateJMXDomains = true;
if (clustered) {
gcb = gcb.clusteredDefault();
gcb.transport().clusterName("test-clustering-" + threadId);
}
gcb.jmx()
.domain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + threadId).enable();
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + threadId).enable();
EmbeddedCacheManager cacheManager = new DefaultCacheManager(gcb.build());
Configuration invalidationCacheConfiguration = getCacheBackedByRemoteStore(threadId, cacheName, builderClass);
cacheManager.defineConfiguration(cacheName, invalidationCacheConfiguration);
cacheManager.defineConfiguration("local", new ConfigurationBuilder().build());
return cacheManager;
}
@ -71,8 +61,6 @@ class TestCacheManagerFactory {
private <T extends StoreConfigurationBuilder<?, T> & RemoteStoreConfigurationChildBuilder<T>> Configuration getCacheBackedByRemoteStore(int threadId, String cacheName, Class<T> builderClass) {
ConfigurationBuilder cacheConfigBuilder = new ConfigurationBuilder();
//String host = "localhost";
//int port = threadId==1 ? 12232 : 13232;
String host = threadId==1 ? "jdg1" : "jdg2";
int port = 11222;
@ -88,7 +76,6 @@ class TestCacheManagerFactory {
.forceReturnValues(false)
.marshaller(KeycloakHotRodMarshallerFactory.class.getName())
.protocolVersion(ProtocolVersion.PROTOCOL_VERSION_29)
//.maxBatchSize(5)
.addServer()
.host(host)
.port(port)

View file

@ -156,8 +156,7 @@ public class InfinispanKeyStorageProviderTest {
protected Cache<String, PublicKeysEntry> getKeysCache() {
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
gcb.globalJmxStatistics().allowDuplicateDomains(true).enabled(true);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
final DefaultCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder cb = new ConfigurationBuilder();
@ -167,8 +166,8 @@ public class InfinispanKeyStorageProviderTest {
.size(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
cb.jmxStatistics().enabled(true);
Configuration cfg = cb.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.KEYS_CACHE_NAME, cfg);
return cacheManager.getCache(InfinispanConnectionProvider.KEYS_CACHE_NAME);
}
}

View file

@ -31,28 +31,18 @@ public class ClusteredCacheBehaviorTest {
public EmbeddedCacheManager createManager() {
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("jgroups.tcp.port", "53715");
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
boolean clustered = true;
boolean async = false;
boolean allowDuplicateJMXDomains = true;
if (clustered) {
gcb = gcb.clusteredDefault();
gcb.transport().clusterName("test-clustering");
}
gcb.globalJmxStatistics().allowDuplicateDomains(allowDuplicateJMXDomains);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
EmbeddedCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder invalidationConfigBuilder = new ConfigurationBuilder();
if (clustered) {
invalidationConfigBuilder.clustering().cacheMode(async ? CacheMode.INVALIDATION_ASYNC : CacheMode.INVALIDATION_SYNC);
}
invalidationConfigBuilder.clustering().cacheMode(CacheMode.INVALIDATION_SYNC);
Configuration invalidationCacheConfiguration = invalidationConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_CACHE_NAME, invalidationCacheConfiguration);
return cacheManager;
}

View file

@ -13,8 +13,8 @@ import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -65,13 +65,9 @@ public class ConcurrencyLockingTest {
protected DefaultCacheManager getVersionedCacheManager() {
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
boolean allowDuplicateJMXDomains = true;
gcb.globalJmxStatistics().allowDuplicateDomains(allowDuplicateJMXDomains);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
final DefaultCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder invalidationConfigBuilder = new ConfigurationBuilder();
Configuration invalidationCacheConfiguration = invalidationConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_CACHE_NAME, invalidationCacheConfiguration);
@ -81,8 +77,8 @@ public class ConcurrencyLockingTest {
counterConfigBuilder.transaction().transactionManagerLookup(new EmbeddedTransactionManagerLookup());
counterConfigBuilder.transaction().lockingMode(LockingMode.PESSIMISTIC);
Configuration counterCacheConfiguration = counterConfigBuilder.build();
cacheManager.defineConfiguration("COUNTER_CACHE", counterCacheConfiguration);
return cacheManager;
}

View file

@ -235,18 +235,9 @@ public class ConcurrencyVersioningTest {
protected DefaultCacheManager getVersionedCacheManager() {
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
boolean clustered = false;
boolean async = false;
boolean allowDuplicateJMXDomains = true;
if (clustered) {
gcb.transport().defaultTransport();
}
gcb.globalJmxStatistics().allowDuplicateDomains(allowDuplicateJMXDomains);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
final DefaultCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder invalidationConfigBuilder = new ConfigurationBuilder();
invalidationConfigBuilder
//.invocationBatching().enable()
@ -259,14 +250,9 @@ public class ConcurrencyVersioningTest {
//.writeSkewCheck(true).versioning()
//.enable().scheme(VersioningScheme.SIMPLE);
//invalidationConfigBuilder.locking().isolationLevel(IsolationLevel.REPEATABLE_READ).writeSkewCheck(true).versioning().enable().scheme(VersioningScheme.SIMPLE);
if (clustered) {
invalidationConfigBuilder.clustering().cacheMode(async ? CacheMode.INVALIDATION_ASYNC : CacheMode.INVALIDATION_SYNC);
}
Configuration invalidationCacheConfiguration = invalidationConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_CACHE_NAME, invalidationCacheConfiguration);
return cacheManager;
}
}

View file

@ -189,35 +189,24 @@ public class DistributedCacheConcurrentWritesTest {
public static EmbeddedCacheManager createManager(String nodeName) {
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("jgroups.tcp.port", "53715");
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
boolean clustered = true;
boolean async = false;
boolean allowDuplicateJMXDomains = true;
if (clustered) {
gcb = gcb.clusteredDefault();
gcb.transport().clusterName("test-clustering");
gcb.transport().nodeName(nodeName);
}
gcb.globalJmxStatistics().allowDuplicateDomains(allowDuplicateJMXDomains);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
EmbeddedCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder distConfigBuilder = new ConfigurationBuilder();
if (clustered) {
distConfigBuilder.clustering().cacheMode(async ? CacheMode.DIST_ASYNC : CacheMode.DIST_SYNC);
distConfigBuilder.clustering().cacheMode(CacheMode.DIST_SYNC);
distConfigBuilder.clustering().hash().numOwners(1);
// Disable L1 cache
distConfigBuilder.clustering().hash().l1().enabled(false);
}
Configuration distConfig = distConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME, distConfig);
return cacheManager;
return cacheManager;
}

View file

@ -162,25 +162,16 @@ public class DistributedCacheWriteSkewTest {
public static EmbeddedCacheManager createManager(String nodeName) {
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("jgroups.tcp.port", "53715");
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
boolean clustered = true;
boolean async = false;
boolean allowDuplicateJMXDomains = true;
if (clustered) {
gcb = gcb.clusteredDefault();
gcb.transport().clusterName("test-clustering");
gcb.transport().nodeName(nodeName);
}
gcb.globalJmxStatistics().allowDuplicateDomains(allowDuplicateJMXDomains);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
EmbeddedCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder distConfigBuilder = new ConfigurationBuilder();
if (clustered) {
distConfigBuilder.clustering().cacheMode(async ? CacheMode.DIST_ASYNC : CacheMode.DIST_SYNC);
distConfigBuilder.clustering().cacheMode(CacheMode.DIST_SYNC);
distConfigBuilder.clustering().hash().numOwners(1);
// Disable L1 cache
@ -191,6 +182,7 @@ public class DistributedCacheWriteSkewTest {
// KEYCLOAK-13692 - Per ISPN-7613 Infinispan:
// * Automatically enables versioning when needed,
// * writeSkewCheck automatically enabled for OPTIMISTIC and REPEATABLE_READ transactions
// so the following explicit settings of these are not needed anymore
// distConfigBuilder.versioning().enabled(true);
// distConfigBuilder.versioning().scheme(VersioningScheme.SIMPLE);
// distConfigBuilder.locking().writeSkewCheck(true);
@ -199,21 +191,14 @@ public class DistributedCacheWriteSkewTest {
distConfigBuilder.locking().concurrencyLevel(32);
distConfigBuilder.locking().lockAcquisitionTimeout(1000, TimeUnit.SECONDS);
// KEYCLOAK-13692 - Per ISPN-7613 Infinispan:
// * Automatically enables versioning when needed,
// * writeSkewCheck automatically enabled for OPTIMISTIC and REPEATABLE_READ transactions
// distConfigBuilder.versioning().enabled(true);
// distConfigBuilder.versioning().scheme(VersioningScheme.SIMPLE);
// distConfigBuilder.invocationBatching().enable();
//distConfigBuilder.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
distConfigBuilder.transaction().transactionManagerLookup(new EmbeddedTransactionManagerLookup());
distConfigBuilder.transaction().lockingMode(LockingMode.OPTIMISTIC);
}
Configuration distConfig = distConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME, distConfig);
return cacheManager;
return cacheManager;
}
}

View file

@ -30,6 +30,7 @@ import org.infinispan.manager.EmbeddedCacheManager;
import org.jboss.logging.Logger;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
/**
* Reproducer for RHSSO-377 / ISPN-6806
@ -132,16 +133,13 @@ public class L1SerializationIssueTest {
private EmbeddedCacheManager createManager() {
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("jgroups.tcp.port", "53715");
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
gcb = gcb.clusteredDefault();
gcb.transport().clusterName("test-clustering");
gcb.globalJmxStatistics().allowDuplicateDomains(true);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
EmbeddedCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder distConfigBuilder = new ConfigurationBuilder();
ClusteringConfigurationBuilder clusterConfBuilder = distConfigBuilder.clustering();
clusterConfBuilder.cacheMode(CacheMode.DIST_SYNC);
@ -149,10 +147,9 @@ public class L1SerializationIssueTest {
clusterConfBuilder.l1().enabled(L1_ENABLED)
.lifespan(L1_LIFESPAN_MS)
.cleanupTaskFrequency(L1_CLEANER_MS);
Configuration distCacheConfiguration = distConfigBuilder.build();
cacheManager.defineConfiguration(CACHE_NAME, distCacheConfiguration);
return cacheManager;
}

View file

@ -96,26 +96,15 @@ public class OutdatedTopologyExceptionReproducerTest {
private EmbeddedCacheManager createManager() {
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("jgroups.tcp.port", "53715");
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
boolean clustered = true;
boolean async = false;
boolean allowDuplicateJMXDomains = true;
if (clustered) {
gcb = gcb.clusteredDefault();
gcb.transport().clusterName("test-clustering");
}
gcb.globalJmxStatistics().allowDuplicateDomains(allowDuplicateJMXDomains);
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
EmbeddedCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder invalidationConfigBuilder = new ConfigurationBuilder();
if (clustered) {
invalidationConfigBuilder.clustering().cacheMode(async ? CacheMode.INVALIDATION_ASYNC : CacheMode.INVALIDATION_SYNC);
}
invalidationConfigBuilder.clustering().cacheMode(CacheMode.INVALIDATION_SYNC);
// Uncomment this to have test fixed!!!
// invalidationConfigBuilder.customInterceptors()
@ -124,10 +113,9 @@ public class OutdatedTopologyExceptionReproducerTest {
// .interceptorClass(StateTransferInterceptor.class);
Configuration invalidationCacheConfiguration = invalidationConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_CACHE_NAME, invalidationCacheConfiguration);
return cacheManager;
return cacheManager;
}
private class CacheOperations extends Thread {

38
pom.xml
View file

@ -22,7 +22,7 @@
<parent>
<groupId>org.jboss</groupId>
<artifactId>jboss-parent</artifactId>
<version>35</version>
<version>37</version>
</parent>
<name>Keycloak</name>
@ -52,10 +52,10 @@
<product.rhsso.version>7.4.0.GA</product.rhsso.version>
<product.build-time>${timestamp}</product.build-time>
<wildfly.version>20.0.1.Final</wildfly.version>
<wildfly.version>21.0.1.Final</wildfly.version>
<wildfly.build-tools.version>1.2.13.Final</wildfly.build-tools.version>
<eap.version>7.4.0.CD20-redhat-00001</eap.version>
<wildfly.core.version>12.0.3.Final</wildfly.core.version>
<wildfly.core.version>13.0.3.Final</wildfly.core.version>
<jboss.as.version>7.2.0.Final</jboss.as.version>
<jboss.as.subsystem.test.version>7.5.22.Final-redhat-1</jboss.as.subsystem.test.version>
@ -63,22 +63,22 @@
<!-- Versions used mostly for Undertow server, aligned with WildFly -->
<jboss.aesh.version>0.66.19</jboss.aesh.version>
<aesh.version>2.4</aesh.version>
<apache.httpcomponents.version>4.5.12</apache.httpcomponents.version>
<apache.httpcomponents.version>4.5.13</apache.httpcomponents.version>
<apache.httpcomponents.httpcore.version>4.4.13</apache.httpcomponents.httpcore.version>
<apache.mime4j.version>0.6</apache.mime4j.version>
<jboss.dmr.version>1.5.1.Final</jboss.dmr.version>
<bouncycastle.version>1.65</bouncycastle.version>
<cxf.version>3.3.6</cxf.version>
<cxf.jetty.version>3.3.6</cxf.jetty.version>
<cxf.jaxrs.version>3.3.6</cxf.jaxrs.version>
<cxf.undertow.version>3.3.6</cxf.undertow.version>
<cxf.version>3.3.7</cxf.version>
<cxf.jetty.version>3.3.7</cxf.jetty.version>
<cxf.jaxrs.version>3.3.7</cxf.jaxrs.version>
<cxf.undertow.version>3.3.7</cxf.undertow.version>
<dom4j.version>2.1.3</dom4j.version>
<h2.version>1.4.197</h2.version>
<jakarta.persistence.version>2.2.3</jakarta.persistence.version>
<hibernate.core.version>5.3.17.Final</hibernate.core.version>
<hibernate.c3p0.version>5.3.17.Final</hibernate.c3p0.version>
<infinispan.version>10.1.8.Final</infinispan.version>
<jackson.version>2.10.4</jackson.version>
<hibernate.core.version>5.3.20.Final</hibernate.core.version>
<hibernate.c3p0.version>5.3.20.Final</hibernate.c3p0.version>
<infinispan.version>11.0.4.Final</infinispan.version>
<jackson.version>2.10.5</jackson.version>
<jackson.databind.version>${jackson.version}</jackson.databind.version>
<jackson.annotations.version>${jackson.databind.version}</jackson.annotations.version>
<jakarta.mail.version>1.6.5</jakarta.mail.version>
@ -89,7 +89,7 @@
<jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec.version>2.0.0.Final</jboss.spec.javax.xml.bind.jboss-jaxb-api_2.3_spec.version>
<jboss.spec.javax.servlet.jsp.jboss-jsp-api_2.3_spec.version>2.0.0.Final</jboss.spec.javax.servlet.jsp.jboss-jsp-api_2.3_spec.version>
<log4j.version>1.2.17</log4j.version>
<resteasy.version>3.12.1.Final</resteasy.version>
<resteasy.version>3.13.2.Final</resteasy.version>
<resteasy.undertow.version>${resteasy.version}</resteasy.undertow.version>
<owasp.html.sanitizer.version>20191001.1</owasp.html.sanitizer.version>
<slf4j-api.version>1.7.30</slf4j-api.version>
@ -100,9 +100,9 @@
<sun.xml.ws.version>2.3.1</sun.xml.ws.version>
<sun.activation.version>1.2.1</sun.activation.version>
<org.glassfish.jaxb.xsom.version>2.3.3-b02</org.glassfish.jaxb.xsom.version>
<undertow.version>2.1.3.Final</undertow.version>
<elytron.version>1.12.1.Final</elytron.version>
<elytron.undertow-server.version>1.7.1.Final</elytron.undertow-server.version>
<undertow.version>2.2.2.Final</undertow.version>
<elytron.version>1.13.1.Final</elytron.version>
<elytron.undertow-server.version>1.8.0.Final</elytron.undertow-server.version>
<jetty92.version>9.2.4.v20141103</jetty92.version>
<jetty93.version>9.3.9.v20160517</jetty93.version>
<jetty94.version>9.4.29.v20200521</jetty94.version>
@ -111,7 +111,7 @@
<glassfish.json.version>1.1.6</glassfish.json.version>
<wildfly.common.version>1.5.2.Final</wildfly.common.version>
<ua-parser.version>1.4.3</ua-parser.version>
<picketbox.version>5.0.3.Final-redhat-00005</picketbox.version>
<picketbox.version>5.0.3.Final-redhat-00006</picketbox.version>
<google.guava.version>25.0-jre</google.guava.version>
<!-- Openshift -->
@ -119,7 +119,7 @@
<!-- Others -->
<commons-lang.version>2.6</commons-lang.version>
<commons-lang3.version>3.9</commons-lang3.version>
<commons-lang3.version>3.10</commons-lang3.version>
<commons-io.version>2.6</commons-io.version>
<apacheds.version>2.0.0.AM26</apacheds.version>
<apacheds.codec.version>2.0.0</apacheds.codec.version>
@ -157,7 +157,7 @@
<jmeter.analysis.plugin.version>1.0.4</jmeter.analysis.plugin.version>
<minify.plugin.version>1.7.6</minify.plugin.version>
<osgi.bundle.plugin.version>2.3.7</osgi.bundle.plugin.version>
<wildfly.plugin.version>2.0.0.Final</wildfly.plugin.version>
<wildfly.plugin.version>2.0.1.Final</wildfly.plugin.version>
<nexus.staging.plugin.version>1.6.5</nexus.staging.plugin.version>
<frontend.plugin.version>1.8.0</frontend.plugin.version>
<docker.maven.plugin.version>0.28.0</docker.maven.plugin.version>

View file

@ -18,20 +18,24 @@
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:10.1 http://www.infinispan.org/schemas/infinispan-config-10.1.xsd"
xmlns="urn:infinispan:config:10.1">
xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd"
xmlns="urn:infinispan:config:11.0">
<cache-container name="keycloak">
<transport lock-timeout="60000"/>
<local-cache name="realms">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="users">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<distributed-cache name="sessions" owners="1"/>
<distributed-cache name="authenticationSessions" owners="1"/>
@ -40,22 +44,28 @@
<distributed-cache name="offlineClientSessions" owners="1"/>
<distributed-cache name="loginFailures" owners="1"/>
<local-cache name="authorization">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<replicated-cache name="work"/>
<local-cache name="keys">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="3600000"/>
<memory>
<object size="1000"/>
</memory>
<memory storage="HEAP" max-count="1000"/>
</local-cache>
<distributed-cache name="actionTokens" owners="2">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="-1" interval="300000"/>
<memory>
<object size="-1"/>
</memory>
<memory storage="HEAP" max-count="-1"/>
</distributed-cache>
</cache-container>
</infinispan>

View file

@ -18,22 +18,26 @@
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:10.1 http://www.infinispan.org/schemas/infinispan-config-10.1.xsd"
xmlns="urn:infinispan:config:10.1">
xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd"
xmlns="urn:infinispan:config:11.0">
<cache-container name="keycloak">
<local-cache name="default">
<transaction transaction-manager-lookup="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup"/>
</local-cache>
<local-cache name="realms">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="users">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="sessions"/>
<local-cache name="authenticationSessions"/>
@ -43,21 +47,27 @@
<local-cache name="loginFailures"/>
<local-cache name="work"/>
<local-cache name="authorization">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="keys">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="3600000"/>
<memory>
<object size="10000"/>
</memory>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="actionTokens">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="-1" interval="300000"/>
<memory>
<object size="-1"/>
</memory>
<memory storage="HEAP" max-count="-1"/>
</local-cache>
</cache-container>
</infinispan>

View file

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version='1.0' encoding='UTF-8'?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
@ -15,9 +15,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@ -42,9 +40,9 @@
<app.server>undertow</app.server>
<!-- Wildfly deprecated versions -->
<wildfly.deprecated.version>19.1.0.Final</wildfly.deprecated.version>
<wildfly.deprecated.wildfly.core.version>11.1.1.Final</wildfly.deprecated.wildfly.core.version>
<wildfly.deprecated.arquillian.wildfly.container>2.1.1.Final</wildfly.deprecated.arquillian.wildfly.container>
<wildfly.deprecated.version>20.0.1.Final</wildfly.deprecated.version>
<wildfly.deprecated.wildfly.core.version>12.0.3.Final</wildfly.deprecated.wildfly.core.version>
<wildfly.deprecated.arquillian.wildfly.container>2.2.0.Final</wildfly.deprecated.arquillian.wildfly.container>
<!--component versions-->
<arquillian-core.version>1.6.0.Final</arquillian-core.version>
@ -442,7 +440,7 @@
<keycloak.connectionsJpa.driver>org.h2.Driver</keycloak.connectionsJpa.driver>
<keycloak.connectionsJpa.database>keycloak</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>sa</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password></keycloak.connectionsJpa.password>
<keycloak.connectionsJpa.password/>
<keycloak.connectionsJpa.url>jdbc:h2:mem:test;MVCC=TRUE;DB_CLOSE_DELAY=-1</keycloak.connectionsJpa.url>
</properties>
</profile>

View file

@ -18,21 +18,25 @@
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:10.1 http://www.infinispan.org/schemas/infinispan-config-10.1.xsd"
xmlns="urn:infinispan:config:10.1">
xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd"
xmlns="urn:infinispan:config:11.0">
<!-- Distributed Cache Container Configuration -->
<cache-container name="keycloak">
<transport lock-timeout="60000" node-name="${jboss.node.name}" />
<local-cache name="realms">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="users">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<distributed-cache name="sessions" owners="${session.cache.owners}"/>
<distributed-cache name="authenticationSessions" owners="${session.cache.owners}"/>
@ -41,22 +45,28 @@
<distributed-cache name="offlineClientSessions" owners="${offline.session.cache.owners}"/>
<distributed-cache name="loginFailures" owners="${login.failure.cache.owners}"/>
<local-cache name="authorization">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<replicated-cache name="work"/>
<local-cache name="keys">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="3600000"/>
<memory>
<object size="1000"/>
</memory>
<memory storage="HEAP" max-count="1000"/>
</local-cache>
<distributed-cache name="actionTokens" owners="2">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="-1" interval="300000"/>
<memory>
<object size="-1"/>
</memory>
<memory storage="HEAP" max-count="-1"/>
</distributed-cache>
</cache-container>
</infinispan>

View file

@ -18,8 +18,8 @@
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:10.1 http://www.infinispan.org/schemas/infinispan-config-10.1.xsd"
xmlns="urn:infinispan:config:10.1">
xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd"
xmlns="urn:infinispan:config:11.0">
<!-- Local Cache Container Configuration -->
<cache-container name="keycloak">
@ -27,14 +27,18 @@
<transaction transaction-manager-lookup="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup"/>
</local-cache>
<local-cache name="realms">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="users">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="sessions"/>
<local-cache name="authenticationSessions"/>
@ -44,21 +48,27 @@
<local-cache name="loginFailures"/>
<local-cache name="work"/>
<local-cache name="authorization">
<memory>
<object size="10000"/>
</memory>
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="keys">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="3600000"/>
<memory>
<object size="10000"/>
</memory>
<memory storage="HEAP" max-count="10000"/>
</local-cache>
<local-cache name="actionTokens">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="-1" interval="300000"/>
<memory>
<object size="-1"/>
</memory>
<memory storage="HEAP" max-count="-1"/>
</local-cache>
</cache-container>
</infinispan>

View file

@ -218,6 +218,7 @@
<directory>src/test/resources</directory>
<includes>
<include>arquillian.xml</include>
<include>wildfly-config.xml</include>
<include>password-blacklists/**</include>
<include>log4j.properties</include>
<include>vault/**</include>

View file

@ -71,6 +71,8 @@ import java.io.FileFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Provider;
import java.security.Security;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -81,12 +83,19 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.ws.rs.NotFoundException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.jboss.arquillian.test.spi.event.suite.After;
import org.jboss.arquillian.test.spi.event.suite.Before;
import org.jboss.shrinkwrap.api.importer.ZipImporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Assert;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import static org.keycloak.testsuite.util.ServerURLs.getAuthServerContextRoot;
import static org.keycloak.testsuite.util.ServerURLs.removeDefaultPorts;
@ -402,6 +411,8 @@ public class AuthServerTestEnricher {
//frontend-only (either load-balancer or auth-server)
log.debug("Starting auth server before suite");
setJsseSecurityProviderForOutboundSslConnectionsOfElytronClient();
try {
startContainerEvent.fire(new StartContainer(suiteContext.getAuthServerInfo().getArquillianContainer()));
} catch (Exception e) {
@ -551,6 +562,194 @@ public class AuthServerTestEnricher {
}
}
/** KEYCLOAK-15692 Work-around the OpenJSSE TlsMasterSecretGenerator error:
*
* https://github.com/openjsse/openjsse/issues/11
*
* To prevent above TLS handshake error when initiating a TLS connection
* ensure:
* * Either both server and client endpoints of the future TLS connection
* simultaneously utilize a JSSE security provider using the OpenJSSE
* extension,
*
* * Or both server and client endpoints simultaneously use a JSSE
* security provider, which doesn't depend on the OpenJSSE extension.
*
* Do this by performing the following:
* * On platforms where implementation of the SunJSSE provider depends on
* OpenJSSE extension ensure only SunJSSE provider is used to define the
* SSL context of the Elytron client used for outbound SSL connections.
*
* * On other platforms, use any suitable JSSE provider by querying all
* the platform providers for respective property.
*
*/
public static void setJsseSecurityProviderForOutboundSslConnectionsOfElytronClient() {
log.info(
"Determining the JSSE security provider to use for outbound " +
"SSL/TLS connections of the Elytron client..."
);
/** First locate the wildfly-config.xml to use. Per:
* https://docs.wildfly.org/21/Client_Guide.html#wildfly-config-xml-discovery
*
* 1) try to load it from the 'wildfly.config.url' property
*/
String wildflyConfigXmlPath = System.getProperty("wildfly.config.url");
// 2) If not set, scan the classpath
if (wildflyConfigXmlPath == null) {
log.debug("Scanning classpath to locate wildfly-config.xml...");
final String javaClassPath = System.getProperty("java.class.path");
for (String dir : javaClassPath.split(":")) {
if (!dir.isEmpty()) {
String candidatePath = dir + File.separator +
"wildfly-config.xml";
if (new File(candidatePath).exists()) {
wildflyConfigXmlPath = candidatePath;
log.debugf(
"Using wildfly-config.xml at '%s' location!",
wildflyConfigXmlPath
);
break;
}
}
}
} else {
log.debugf(
"Using wildfly-config.xml from 'wildfly.config.url' " +
"property at '%s' location",
wildflyConfigXmlPath
);
}
// If still not found, that's an error
if (wildflyConfigXmlPath == null) {
throw new RuntimeException(
"Failed to locate the wildfly-config.xml to use for " +
"the configuration of Elytron client!"
);
}
/** Determine the name of the system property from wildfly-config.xml
* holding the name of the security provider which is used by Elytron
* client to define its SSL context for outbound SSL connections.
*/
final File wildflyConfigXml = new File(wildflyConfigXmlPath);
String jsseSecurityProviderSystemProperty = null;
try {
DocumentBuilder documentBuilder = DocumentBuilderFactory
.newInstance().newDocumentBuilder();
Document xmlDoc = documentBuilder.parse(wildflyConfigXml);
NodeList nodeList = xmlDoc.getElementsByTagName("provider-name");
// Sanity check
if (nodeList.getLength() != 1) {
throw new RuntimeException(
"Failed to locate the 'provider-name' element " +
"in wildfly-config.xml XML file!"
);
}
String providerNameElement = nodeList.item(0).getAttributes()
.getNamedItem("name").getNodeValue();
// Drop Wildfly's expressions notation from the attribute's value
jsseSecurityProviderSystemProperty = providerNameElement
.replaceAll("(\\$|\\{|\\}|(:.*$))", new String());
} catch (IOException e) {
throw new RuntimeException(String.format(
"Error reading the '%s' file. Please make sure the provided " +
"path is correct and retry!",
wildflyConfigXml.getAbsolutePath()
));
} catch (ParserConfigurationException|SAXException e) {
throw new RuntimeException(String.format(
"Failed to parse the '%s' XML file!",
wildflyConfigXml.getAbsolutePath()
));
}
boolean determineJsseSecurityProviderName = false;
if (jsseSecurityProviderSystemProperty != null) {
// Does JSSE security provider system property already exist?
if (
System.getProperty(jsseSecurityProviderSystemProperty) == null
) {
// If not, determine it
determineJsseSecurityProviderName = true;
}
} else {
throw new RuntimeException(
"Failed to determine the name of system property " +
"holding JSSE security provider's name for Elytron client!"
);
}
if (determineJsseSecurityProviderName) {
/** Detect if OpenJSSE extension is present on the platform
*
* Since internal 'com.sun.net.ssl.*' classes of the SunJSSE
* provider have identical names regardless if the OpenJSSE
* extension is used or not:
*
* https://github.com/openjsse/openjsse/blob/master/pom.xml#L125
*
* detect the presence of the OpenJSSE extension by checking the
* presence of the 'openjsse.jar' file within the JRE extensions
* directory.
*
*/
final String jreExtensionsDir = System.getProperty("java.home") +
File.separator + "lib" + File.separator + "ext" +
File.separator + "openjsse.jar";
boolean openJsseExtensionPresent = new File(
jreExtensionsDir).exists();
Provider platformJsseProvider = Security
.getProviders("SSLContext.TLSv1.2")[0];
if (platformJsseProvider != null) {
// If OpenJSSE extension is present
if (openJsseExtensionPresent) {
// Sanity check - confirm SunJSSE provider is present on
// the platform (if OpenJSSE extension is present, it
// shouldn't ever happen SunJSSE won't be, but double-check
// for any case)
Provider sunJsseProvider = Stream.of(
Security.getProviders()
).filter(p -> p.getName().equals("SunJSSE"))
.collect(Collectors.toList())
.get(0);
// Use it or throw an error if absent
if (sunJsseProvider != null) {
platformJsseProvider = sunJsseProvider;
} else {
throw new RuntimeException(
"The SunJSSE provider is not present " +
"on the platform!"
);
}
}
// Propagate the final provider name to system property used by
// wildfly-config.xml to configure the JSSE provider name
System.setProperty(
jsseSecurityProviderSystemProperty,
platformJsseProvider.getName()
);
} else {
throw new RuntimeException(
"Cannot identify a security provider for Elytron client " +
"offering the TLSv1.2 capability!"
);
}
log.infof(
"Using the '%s' JSSE provider!", platformJsseProvider.getName()
);
}
}
private static OnlineManagementClient getManagementClient(ContainerInfo containerInfo) {
try {
return ManagementClient.online(OnlineOptions

View file

@ -55,7 +55,7 @@ public class MetricsRestServiceTest extends AbstractKeycloakTest {
try (Response response = client.target("http://" + MGMT_HOST + ":" + MGMT_PORT + "/health").request().get()) {
Assert.assertThat(response, statusCodeIs(Status.OK));
Assert.assertThat(response, body(containsString("{\"status\":\"UP\",\"checks\":[]}")));
Assert.assertThat(response, body(containsString("{\"status\":\"UP\",\"checks\":[{")));
} finally {
client.close();
}

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2020 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~
~ Wildfly Elytron 1.13.0.CR3+ RESTEasy client SSL truststore configuration.
~ Used by instances of javax.ws.rs.client.ClientBuilder within various tests
~ from Keycloak testsuite to create new javax.ws.rs.client.Client instances
~ using the default client builder implementation class provided by the
~ JAX-RS implementation provider.
~
~ See KEYCLOAK-15692, ELY-1891 issues & PRs of EAP7-1219 issue for details.
~
~ Note: This file (constituting the configuration of the Elytron client that
~ should be used) is to be discovered automagically per:
~
~ https://docs.wildfly.org/21/Client_Guide.html#wildfly-config-xml-discovery
~ since:
~ 1) It's named 'wildfly-config.xml' and
~ 2) Is present in the class path.
~
~ Alternatively, set the 'wildfly.config.url' system property to point the
~ client to the location where its configuration resides.
~
-->
<configuration>
<authentication-client xmlns="urn:elytron:client:1.4">
<key-stores>
<key-store name="client-side-truststore" type="JKS">
<file name="${client.truststore:}"/>
<key-store-clear-password password="${client.truststore.passphrase:secret}"/>
</key-store>
</key-stores>
<ssl-contexts>
<ssl-context name="wildfly-elytron-resteasy-client-context">
<trust-store key-store-name="client-side-truststore"/>
<provider-name name="${elytron.client.outbound.ssl.jsse.provider:}"/>
</ssl-context>
</ssl-contexts>
<ssl-context-rules>
<rule use-ssl-context="wildfly-elytron-resteasy-client-context"/>
</ssl-context-rules>
</authentication-client>
</configuration>

View file

@ -60,7 +60,7 @@
<artifactId>integration-arquillian-tests-base</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<includes>arquillian.xml,keycloak-add-user.json,test-constants.properties,kerberos/*,keystore/*,password-blacklists/*,log4j.properties,vault/*</includes>
<includes>arquillian.xml,wildfly-config.xml,keycloak-add-user.json,test-constants.properties,kerberos/*,keystore/*,password-blacklists/*,log4j.properties,vault/*</includes>
</artifactItem>
</artifactItems>
</configuration>

View file

@ -214,14 +214,14 @@
<skip.add.user.json>false</skip.add.user.json>
<skip.clean.second.cache>true</skip.clean.second.cache>
<skip.copy.auth.crossdc.nodes>true</skip.copy.auth.crossdc.nodes>
<client.certificate.keystore>${auth.server.config.dir}/client.jks</client.certificate.keystore>
<client.certificate.keystore.passphrase>secret</client.certificate.keystore.passphrase>
<client.truststore>${auth.server.config.dir}/keycloak.truststore</client.truststore>
<client.truststore.passphrase>secret</client.truststore.passphrase>
<client.certificate.ca.path>${auth.server.config.dir}/ca.crt</client.certificate.ca.path>
<client.certificate.file>${auth.server.config.dir}/client.crt</client.certificate.file>
<client.certificate.keystore>${auth.server.config.dir}/client.jks</client.certificate.keystore>
<client.certificate.keystore.passphrase>secret</client.certificate.keystore.passphrase>
<client.key.file>${auth.server.config.dir}/client.key</client.key.file>
<client.key.passphrase>secret</client.key.passphrase>
<client.truststore>${auth.server.config.dir}/keycloak.truststore</client.truststore>
<client.truststore.passphrase>secret</client.truststore.passphrase>
<!-- KEYCLOAK-6771 Certificate Bound Token -->
<hok.client.certificate.keystore>${auth.server.config.dir}/other_client.jks</hok.client.certificate.keystore>
@ -601,13 +601,13 @@
<project.version>${project.version}</project.version>
<client.certificate.ca.path>${client.certificate.ca.path}</client.certificate.ca.path>
<client.certificate.file>${client.certificate.file}</client.certificate.file>
<client.certificate.keystore>${client.certificate.keystore}</client.certificate.keystore>
<client.certificate.keystore.passphrase>${client.certificate.keystore.passphrase}</client.certificate.keystore.passphrase>
<client.truststore>${client.truststore}</client.truststore>
<client.truststore.passphrase>${client.truststore.passphrase}</client.truststore.passphrase>
<client.certificate.file>${client.certificate.file}</client.certificate.file>
<client.key.file>${client.key.file}</client.key.file>
<client.key.passphrase>${client.key.passphrase}</client.key.passphrase>
<client.truststore>${client.truststore}</client.truststore>
<client.truststore.passphrase>${client.truststore.passphrase}</client.truststore.passphrase>
<!-- KEYCLOAK-6771 Certificate Bound Token -->
<hok.client.certificate.keystore>${hok.client.certificate.keystore}</hok.client.certificate.keystore>
@ -653,6 +653,12 @@
<keycloak.connectionsJpa.database>${keycloak.connectionsJpa.database}</keycloak.connectionsJpa.database>
<keycloak.connectionsJpa.user>${keycloak.connectionsJpa.user}</keycloak.connectionsJpa.user>
<keycloak.connectionsJpa.password>${keycloak.connectionsJpa.password}</keycloak.connectionsJpa.password>
<!--
~ Used for Wildfly Elytron 1.13.0.CR3+ RESTEasy client SSL truststore configuration.
~ See KEYCLOAK-15692, ELY-1891 issues & PRs of EAP7-1219 issue for details.
-->
<wildfly.config.url>${project.build.directory}/dependency/wildfly-config.xml</wildfly.config.url>
</systemPropertyVariables>
<properties>
<property>

View file

@ -19,7 +19,7 @@
<!-- See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
<config>
<extension-module>org.jboss.as.connector</extension-module>
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<subsystem xmlns="urn:jboss:domain:datasources:6.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>

View file

@ -15,21 +15,20 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!-- See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
<config default-supplement="default">
<extension-module>org.jboss.as.clustering.infinispan</extension-module>
<subsystem xmlns="urn:jboss:domain:infinispan:10.0">
<subsystem xmlns="urn:jboss:domain:infinispan:11.0">
<?CACHE-CONTAINERS?>
</subsystem>
<supplement name="default">
<replacement placeholder="CACHE-CONTAINERS">
<cache-container name="keycloak" module="org.keycloak.keycloak-model-infinispan">
<local-cache name="realms">
<object-memory size="10000"/>
<heap-memory size="10000"/>
</local-cache>
<local-cache name="users">
<object-memory size="10000"/>
<heap-memory size="10000"/>
</local-cache>
<local-cache name="sessions"/>
<local-cache name="authenticationSessions"/>
@ -39,14 +38,14 @@
<local-cache name="loginFailures"/>
<local-cache name="work"/>
<local-cache name="authorization">
<object-memory size="10000"/>
<heap-memory size="10000"/>
</local-cache>
<local-cache name="keys">
<object-memory size="1000"/>
<heap-memory size="1000"/>
<expiration max-idle="3600000"/>
</local-cache>
<local-cache name="actionTokens">
<object-memory size="-1"/>
<heap-memory size="-1"/>
<expiration max-idle="-1" interval="300000"/>
</local-cache>
</cache-container>
@ -76,11 +75,11 @@
</cache-container>
<cache-container name="hibernate" module="org.infinispan.hibernate-cache">
<local-cache name="entity">
<object-memory size="10000"/>
<heap-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
<object-memory size="10000"/>
<heap-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps"/>
@ -92,10 +91,10 @@
<cache-container name="keycloak" module="org.keycloak.keycloak-model-infinispan">
<transport lock-timeout="60000"/>
<local-cache name="realms">
<object-memory size="10000"/>
<heap-memory size="10000"/>
</local-cache>
<local-cache name="users">
<object-memory size="10000"/>
<heap-memory size="10000"/>
</local-cache>
<distributed-cache name="sessions" owners="1"/>
<distributed-cache name="authenticationSessions" owners="1"/>
@ -104,15 +103,15 @@
<distributed-cache name="offlineClientSessions" owners="1"/>
<distributed-cache name="loginFailures" owners="1"/>
<local-cache name="authorization">
<object-memory size="10000"/>
<heap-memory size="10000"/>
</local-cache>
<replicated-cache name="work"/>
<local-cache name="keys">
<object-memory size="1000"/>
<heap-memory size="1000"/>
<expiration max-idle="3600000"/>
</local-cache>
<distributed-cache name="actionTokens" owners="2">
<object-memory size="-1"/>
<heap-memory size="-1"/>
<expiration max-idle="-1" interval="300000"/>
</distributed-cache>
</cache-container>
@ -146,12 +145,12 @@
<cache-container name="hibernate" module="org.infinispan.hibernate-cache">
<transport lock-timeout="60000"/>
<local-cache name="local-query">
<object-memory size="10000"/>
<heap-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<invalidation-cache name="entity">
<transaction mode="NON_XA"/>
<object-memory size="10000"/>
<heap-memory size="10000"/>
<expiration max-idle="100000"/>
</invalidation-cache>
<replicated-cache name="timestamps"/>

View file

@ -24,7 +24,7 @@
<!-- See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
<config>
<extension-module>org.wildfly.extension.undertow</extension-module>
<subsystem xmlns="urn:jboss:domain:undertow:10.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
<subsystem xmlns="urn:jboss:domain:undertow:11.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
<buffer-cache name="default"/>
<server name="default-server">
<?AJP?>