Compare commits
106 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
aa213c3003 | |
|
|
88cbaebd1a | |
|
|
e072c7642b | |
|
|
b5f110c659 | |
|
|
95b1c390b2 | |
|
|
858a12b3ff | |
|
|
7c07c3c135 | |
|
|
2cfce0568a | |
|
|
c51919d1e3 | |
|
|
1fc4e07988 | |
|
|
799fcb1d0e | |
|
|
2e27c47f2f | |
|
|
b8e0397b0a | |
|
|
661d852250 | |
|
|
ba6f30f963 | |
|
|
dbe167276a | |
|
|
28002fb835 | |
|
|
6cdf6f655a | |
|
|
7dc7a61511 | |
|
|
60262e3a72 | |
|
|
5d79a849ef | |
|
|
3fef2347f0 | |
|
|
aebdc3a04d | |
|
|
a691074548 | |
|
|
f9f4c8e5d5 | |
|
|
4f8a84cb1d | |
|
|
6f40c9856f | |
|
|
62f301c42d | |
|
|
9422bf86ac | |
|
|
be4383abac | |
|
|
fa7d6442f5 | |
|
|
e1ae06ec50 | |
|
|
901a30ea8c | |
|
|
76913d93c2 | |
|
|
dc7edf634e | |
|
|
12a3a8a8e7 | |
|
|
3fb1df91f7 | |
|
|
0e3b7c107c | |
|
|
978f2cdd21 | |
|
|
f547c681a8 | |
|
|
06e14c854d | |
|
|
d077bdd93d | |
|
|
96ac9beb7f | |
|
|
4e067e94d7 | |
|
|
e3ccf70b64 | |
|
|
6b584db971 | |
|
|
cc4dac0922 | |
|
|
151ef89772 | |
|
|
bda80f1d7b | |
|
|
3ecfbcd8b1 | |
|
|
f7a49f9fec | |
|
|
ebca10356e | |
|
|
7fe2a4dd3f | |
|
|
7acf4cc2d9 | |
|
|
5baa3a7ccf | |
|
|
f34e80450b | |
|
|
974c1b1890 | |
|
|
6ca7127939 | |
|
|
b9317fd1af | |
|
|
b5e1e2a4a2 | |
|
|
92b37d2b6e | |
|
|
7192bf1302 | |
|
|
c68b96d762 | |
|
|
77011bb3c8 | |
|
|
72f191bcda | |
|
|
2c198333ef | |
|
|
26cf509ea7 | |
|
|
cb0c9f9d39 | |
|
|
c4156b61f5 | |
|
|
ba49012fb2 | |
|
|
270be77cc7 | |
|
|
bfb531761d | |
|
|
6e67a3b492 | |
|
|
473f67db7e | |
|
|
b2284aecee | |
|
|
2adb6f6bee | |
|
|
148415c691 | |
|
|
386f84962d | |
|
|
f27f8b1589 | |
|
|
5d645e1d3c | |
|
|
ea9bb95f7c | |
|
|
2f2a939823 | |
|
|
b2ff110da5 | |
|
|
46592e65ce | |
|
|
9a553b6344 | |
|
|
a28e1553d2 | |
|
|
b1da9ef121 | |
|
|
261be8f99d | |
|
|
a3cceea640 | |
|
|
e337edc50f | |
|
|
3bac40d2a3 | |
|
|
f67bbbd52a | |
|
|
74924f84ae | |
|
|
033d310b0d | |
|
|
8731ac153a | |
|
|
a6ea66285f | |
|
|
7686dab07a | |
|
|
9d43803100 | |
|
|
ea67092cbc | |
|
|
6edfa3910f | |
|
|
da5174bf17 | |
|
|
afd7cad8b8 | |
|
|
ce6ed7e9c0 | |
|
|
7d0cfb306c | |
|
|
8d19ea8046 | |
|
|
ff90b44018 |
|
|
@ -11,18 +11,19 @@
|
|||
# Red Hat, Inc. - initial API and implementation
|
||||
|
||||
# Dockerfile to bootstrap build and test in openshift-ci
|
||||
|
||||
FROM registry.ci.openshift.org/openshift/release:golang-1.18
|
||||
# hadolint ignore=DL3002
|
||||
USER 0
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
# Install yq, kubectl, chectl cli used by olm/olm.sh script.
|
||||
RUN yum install --assumeyes -d1 python3-pip httpd-tools && \
|
||||
# hadolint ignore=DL3041
|
||||
# Install yq, kubectl, chectl cli.
|
||||
RUN yum install --assumeyes -d1 psmisc python3-pip httpd-tools nodejs && \
|
||||
pip3 install --upgrade setuptools && \
|
||||
pip3 install yq && \
|
||||
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \
|
||||
chmod +x ./kubectl && \
|
||||
mv ./kubectl /usr/local/bin && \
|
||||
bash <(curl -sL https://www.eclipse.org/che/chectl/) --channel=next && \
|
||||
curl https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.12.4/openshift-client-linux.tar.gz | tar xvzf - -C /usr/local/bin/ oc && \
|
||||
chmod ug+x /usr/local/bin/oc
|
||||
bash <(curl -sL https://che-incubator.github.io/chectl/install.sh) --channel=next
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDDDCCAfSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtpbmdy
|
||||
ZXNzLW9wZXJhdG9yQDE3MDI5MTczMzkwHhcNMjMxMjE4MTYzNTM4WhcNMjUxMjE3
|
||||
MTYzNTM5WjAmMSQwIgYDVQQDDBtpbmdyZXNzLW9wZXJhdG9yQDE3MDI5MTczMzkw
|
||||
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDVfcIyqKLYcrmieDOCvAq
|
||||
RKFR0PXqjl54DyfhkP7TC/rA4WMaJgYamYNNRcy4rOb+i3P1yepeVlXj+4gka41W
|
||||
fh1QghqDGPpQTF7I8SDhnz3qdQymgSSkrxBWOGgJZRG3Gd50CNeh+ADdNlOxzZhJ
|
||||
c1HI9/36Zp0M7RHLNwrYzKf/Scrcl3t/Ps4KHKsNtjNygnPSTjGwza5TTTAvGQ+h
|
||||
3+c+bKJHZp6VFoEpubmBfCG8x+vJwBNI+YauXwti9EqFutnAbOiQ4aOvqQYINngV
|
||||
OQTOg3xnifnooaR2iZPOtxPLUDMydHP9sDVNGLICpnKcFN6x5JKq1fAuwOAMRMQr
|
||||
AgMBAAGjRTBDMA4GA1UdDwEB/wQEAwICpDASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
|
||||
A1UdDgQWBBRQfZkM6C20GT1YiTiS694vRPP2MDANBgkqhkiG9w0BAQsFAAOCAQEA
|
||||
qd9ug2Bo2s3CG0qjNtk19WYYAuwkEMZU9L/FbSfmPkkOTbrZB71ofZbVan8Dx9/W
|
||||
SfbkN1eJQNxd7QIDlExKEW2ufJIMCDe6haLHV8x+z3fISHg3wMUCPtadLG/exafy
|
||||
agfj8PQgnJ1sbA/fKl0rqcVYuIihZ0DdMe28Yj92BFcs5+TXzVYzjyeIGonUZrCR
|
||||
LtW2CxV7Ngue9pkWGsqQSlRwzp3knYfZxeQLneZcGlsSV4r9LOKIAA/MhBGgpwVc
|
||||
zrh7L93jajHD1AD0sRdUQp4VVhysXVmMMSAjaLkqHsvSyJp7yKJOmrts6a274qbU
|
||||
J1E6cXqtfF0NwRo2D9BouQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# Copyright (c) 2023-2024 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -32,48 +32,105 @@ export PRIVATE_REPO_WORKSPACE_NAME=${PRIVATE_REPO_WORKSPACE_NAME:-"private-repo-
|
|||
export PUBLIC_PROJECT_NAME=${PUBLIC_PROJECT_NAME:-"public-repo"}
|
||||
export PRIVATE_PROJECT_NAME=${PRIVATE_PROJECT_NAME:-"private-repo"}
|
||||
export YAML_FILE_NAME=${YAML_FILE_NAME:-"devfile.yaml"}
|
||||
export CUSTOM_CONFIG_MAP_NAME=${CUSTOM_CONFIG_MAP_NAME:-"custom-ca-certificates"}
|
||||
export GIT_SSL_CONFIG_MAP_NAME=${GIT_SSL_CONFIG_MAP_NAME:-"che-self-signed-cert"}
|
||||
|
||||
provisionOpenShiftOAuthUser() {
|
||||
echo -e "[INFO] Provisioning Openshift OAuth user"
|
||||
echo "------- [INFO] Start provisioning Openshift OAuth user -------"
|
||||
htpasswd -c -B -b users.htpasswd ${OCP_ADMIN_USER_NAME} ${OCP_LOGIN_PASSWORD}
|
||||
htpasswd -b users.htpasswd ${OCP_NON_ADMIN_USER_NAME} ${OCP_LOGIN_PASSWORD}
|
||||
oc create secret generic htpass-secret --from-file=htpasswd="users.htpasswd" -n openshift-config
|
||||
oc apply -f ".ci/openshift-ci/htpasswdProvider.yaml"
|
||||
oc adm policy add-cluster-role-to-user cluster-admin ${OCP_ADMIN_USER_NAME}
|
||||
|
||||
echo -e "[INFO] Waiting for htpasswd auth to be working up to 5 minutes"
|
||||
echo "------- [INFO] Waiting for htpasswd auth to be working up to 5 minutes -------"
|
||||
CURRENT_TIME=$(date +%s)
|
||||
ENDTIME=$((CURRENT_TIME + 300))
|
||||
while [ "$(date +%s)" -lt $ENDTIME ]; do
|
||||
if oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false; then
|
||||
break
|
||||
echo "======= [INFO] OpenShift OAuth htpasswd is configured. =======
|
||||
======= [INFO] Login to OCP cluster with admin user credentials is success.======="
|
||||
return 0
|
||||
fi
|
||||
sleep 10
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "####### [ERROR] Error occurred while waiting OpenShift OAuth htpasswd setup. Try to rerun test. #######"
|
||||
exit 1
|
||||
}
|
||||
|
||||
configureGitSelfSignedCertificate() {
|
||||
echo "------- [INFO] Configure self-signed certificate for Git provider -------"
|
||||
oc adm new-project ${CHE_NAMESPACE}
|
||||
oc project ${CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Create ConfigMap with the required TLS certificate -------"
|
||||
oc create configmap ${CUSTOM_CONFIG_MAP_NAME} --from-file=.ci/openshift-ci/ca.crt
|
||||
oc label configmap ${CUSTOM_CONFIG_MAP_NAME} app.kubernetes.io/part-of=che.eclipse.org app.kubernetes.io/component=ca-bundle
|
||||
|
||||
echo "------- [INFO] Create ConfigMap to support Git repositories with self-signed certificates -------"
|
||||
oc create configmap ${GIT_SSL_CONFIG_MAP_NAME} --from-file=.ci/openshift-ci/ca.crt --from-literal=githost=${GIT_PROVIDER_URL}
|
||||
oc label configmap ${GIT_SSL_CONFIG_MAP_NAME} app.kubernetes.io/part-of=che.eclipse.org
|
||||
|
||||
echo "======= [INFO] ConfigMaps are configured ======="
|
||||
}
|
||||
|
||||
createCustomResourcesFile() {
|
||||
echo "------- [INFO] Create custom resourses file -------"
|
||||
cat > custom-resources.yaml <<-END
|
||||
apiVersion: org.eclipse.che/v2
|
||||
spec:
|
||||
devEnvironments:
|
||||
maxNumberOfRunningWorkspacesPerUser: 10000
|
||||
maxNumberOfRunningWorkspacesPerUser: 10000
|
||||
END
|
||||
|
||||
echo "Generated custom resources file"
|
||||
echo "======= [INFO] Generated custom resources file ======="
|
||||
cat custom-resources.yaml
|
||||
}
|
||||
|
||||
patchCustomResourcesFile() {
|
||||
echo "------- [INFO] Edit the custom resources file to add 'gitTrustedCertsConfigMapName' -------"
|
||||
yq -y '.spec.devEnvironments.trustedCerts += {"gitTrustedCertsConfigMapName": "'${GIT_SSL_CONFIG_MAP_NAME}'"}' custom-resources.yaml -i
|
||||
|
||||
echo "======= [INFO] Patched custom resources file ======="
|
||||
cat custom-resources.yaml
|
||||
}
|
||||
|
||||
deployChe() {
|
||||
echo "------- [INFO] Start installing Eclipse Che -------"
|
||||
chectl server:deploy --cheimage=$CHE_SERVER_IMAGE \
|
||||
--che-operator-cr-patch-yaml=custom-resources.yaml \
|
||||
--platform=openshift \
|
||||
--telemetry=off \
|
||||
--batch
|
||||
|
||||
waitFinishDeploymentCheServer
|
||||
echo "======= [INFO] Eclipse Che is successfully installed ======="
|
||||
}
|
||||
|
||||
waitFinishDeploymentCheServer() {
|
||||
CURRENT_TIME=$(date +%s)
|
||||
ENDTIME=$((CURRENT_TIME + 60))
|
||||
|
||||
while [ "$(date +%s)" -lt $ENDTIME ]; do
|
||||
podCheServerName=$(oc get pod -n ${CHE_NAMESPACE} -l component=che | grep "che" | awk '{ print $1 }')
|
||||
echo "Pod Che_Server: $podCheServerName"
|
||||
count=$(echo "$podCheServerName" | wc -l)
|
||||
if [ $count -eq 1 ]; then
|
||||
echo "------- [INFO] Only one Che Server pod is left. -------"
|
||||
return 0
|
||||
fi
|
||||
echo "------- [INFO] Waiting until only one Che Server pod remains. -------"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "####### [ERROR] Error occurred while waiting for only one Che Server pod. #######"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# this command starts port forwarding between the local machine and the che-host service in the OpenShift cluster.
|
||||
forwardPortToService() {
|
||||
echo "------- [INFO] Start forwarding between the local machine and the che-host service -------"
|
||||
oc port-forward service/che-host ${CHE_FORWARDED_PORT}:8080 -n ${CHE_NAMESPACE} &
|
||||
sleep 3s
|
||||
}
|
||||
|
|
@ -98,44 +155,40 @@ requestFactoryResolverGitRepoUrl() {
|
|||
|
||||
# check that factory resolver returns correct value without any PAT/OAuth setup
|
||||
testFactoryResolverNoPatOAuth() {
|
||||
PUBLIC_REPO_URL=$1
|
||||
PRIVATE_REPO_URL=$2
|
||||
echo "------- [INFO] Check factory resolver for public repository with NO PAT/OAuth setup -------"
|
||||
testFactoryResolverResponse $1 200
|
||||
|
||||
echo "[INFO] Check factory resolver for public repository with NO PAT/OAuth setup"
|
||||
if [ "$(requestFactoryResolverGitRepoUrl ${PUBLIC_REPO_URL} | grep "HTTP/1.1 200")" ]; then
|
||||
echo "[INFO] Factory resolver returned 'HTTP/1.1 200' status code."
|
||||
else
|
||||
echo "[ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 200."
|
||||
exit 1
|
||||
fi
|
||||
echo "------- [INFO] Check factory resolver for private repository with NO PAT/OAuth setup -------"
|
||||
testFactoryResolverResponse $2 500
|
||||
}
|
||||
|
||||
echo "[INFO] Check factory resolver for private repository with NO PAT/OAuth setup"
|
||||
if [ "$(requestFactoryResolverGitRepoUrl ${PRIVATE_REPO_URL} | grep "HTTP/1.1 400")" ]; then
|
||||
echo "[INFO] Factory resolver returned 'HTTP/1.1 400' status code. Expected client side error."
|
||||
else
|
||||
echo "[ERROR] Factory resolver returned wrong status code. Expected 'HTTP/1.1 400'."
|
||||
exit 1
|
||||
fi
|
||||
# check that raw devfile url factory resolver returns correct value without any PAT/OAuth setup
|
||||
testFactoryResolverNoPatOAuthRaw() {
|
||||
echo "------- [INFO] Check factory resolver for public repository with NO PAT/OAuth setup -------"
|
||||
testFactoryResolverResponse $1 200
|
||||
|
||||
echo "------- [INFO] Check factory resolver for private repository with NO PAT/OAuth setup -------"
|
||||
testFactoryResolverResponse $2 400
|
||||
}
|
||||
|
||||
# check that factory resolver returns correct value with PAT/OAuth setup
|
||||
testFactoryResolverWithPatOAuth() {
|
||||
PUBLIC_REPO_URL=$1
|
||||
PRIVATE_REPO_URL=$2
|
||||
echo "------- [INFO] Check factory resolver for public repository with PAT/OAuth setup -------"
|
||||
testFactoryResolverResponse $1 200
|
||||
|
||||
echo "[INFO] Check factory resolver for public repository with PAT/OAuth setup"
|
||||
if [ "$(requestFactoryResolverGitRepoUrl ${PUBLIC_REPO_URL} | grep "HTTP/1.1 200")" ]; then
|
||||
echo "[INFO] Factory resolver returned 'HTTP/1.1 200' status code."
|
||||
else
|
||||
echo "[ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 200"
|
||||
exit 1
|
||||
fi
|
||||
echo "------- [INFO] Check factory resolver for private repository with PAT/OAuth setup -------"
|
||||
testFactoryResolverResponse $2 200
|
||||
}
|
||||
|
||||
echo "[INFO] Check factory resolver for private repository with PAT/OAuth setup"
|
||||
if [ "$(requestFactoryResolverGitRepoUrl ${PRIVATE_REPO_URL} | grep "HTTP/1.1 200")" ]; then
|
||||
echo "[INFO] Factory resolver returned 'HTTP/1.1 200' status code."
|
||||
testFactoryResolverResponse() {
|
||||
URL=$1
|
||||
RESPONSE_CODE=$2
|
||||
|
||||
if [ "$(requestFactoryResolverGitRepoUrl ${URL} | grep "HTTP/1.1 ${RESPONSE_CODE}")" ]; then
|
||||
echo "======= [INFO] Factory resolver returned 'HTTP/1.1 ${RESPONSE_CODE}' status code. Expected client side response. ======="
|
||||
else
|
||||
echo "[ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 200"
|
||||
echo "####### [ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 ${RESPONSE_CODE}. #######
|
||||
####### Cause possible: PR code regress or service is changed. Need to investigate it. #######"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
|
@ -153,12 +206,19 @@ requestProvisionNamespace() {
|
|||
initUserNamespace() {
|
||||
OCP_USER_NAME=$1
|
||||
|
||||
echo "[INFO] Initialize user namespace"
|
||||
echo "------- [INFO] Initialize user namespace -------"
|
||||
oc login -u=${OCP_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false
|
||||
if [ "$(requestProvisionNamespace | grep "HTTP/1.1 200")" ]; then
|
||||
echo "[INFO] Request provision user namespace returned 'HTTP/1.1 200' status code."
|
||||
|
||||
request_result=$(requestProvisionNamespace) || true
|
||||
|
||||
if [ -z "$request_result" ]; then
|
||||
echo "####### [ERROR] Cause possible: lost connection to pod, this is an infrastructure problem. Try to rerun the test. #######"
|
||||
exit 1
|
||||
elif [ "$(echo "$request_result" | grep "HTTP/1.1 200")" ]; then
|
||||
echo "======= [INFO] Request provision user namespace returned 'HTTP/1.1 200' status code. User namespace is created. ======="
|
||||
else
|
||||
echo "[ERROR] Request provision user namespace returned wrong status code. Expected: HTTP/1.1 200"
|
||||
echo "####### [ERROR] Request provision user namespace returned wrong status code. Expected: HTTP/1.1 200. #######
|
||||
####### User namespace creation failed. Cause possible: PR code regression or service is changed. Need to investigate. #######"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
|
@ -166,10 +226,9 @@ initUserNamespace() {
|
|||
setupPersonalAccessToken() {
|
||||
GIT_PROVIDER_TYPE=$1
|
||||
GIT_PROVIDER_URL=$2
|
||||
GIT_PROVIDER_USER_ID=$3
|
||||
GIT_PROVIDER_PAT=$4
|
||||
GIT_PROVIDER_PAT=$3
|
||||
|
||||
echo "[INFO] Setup Personal Access Token Secret"
|
||||
echo "------- [INFO] Setup Personal Access Token Secret -------"
|
||||
oc project ${USER_CHE_NAMESPACE}
|
||||
CHE_USER_ID=$(oc get secret user-profile -o jsonpath='{.data.id}' | base64 -d)
|
||||
ENCODED_PAT=$(echo -n ${GIT_PROVIDER_PAT} | base64)
|
||||
|
|
@ -179,12 +238,115 @@ setupPersonalAccessToken() {
|
|||
sed -i "s#che-user-id#${CHE_USER_ID}#g" pat-secret.yaml
|
||||
sed -i "s#git-provider-name#${GIT_PROVIDER_TYPE}#g" pat-secret.yaml
|
||||
sed -i "s#git-provider-url#${GIT_PROVIDER_URL}#g" pat-secret.yaml
|
||||
sed -i "s#git-provider-user-id#${GIT_PROVIDER_USER_ID}#g" pat-secret.yaml
|
||||
sed -i "s#encoded-access-token#${ENCODED_PAT}#g" pat-secret.yaml
|
||||
|
||||
if [ "${GIT_PROVIDER_TYPE}" == "azure-devops" ]; then
|
||||
sed -i "s#''#${GIT_PROVIDER_USERNAME}#g" pat-secret.yaml
|
||||
fi
|
||||
|
||||
cat pat-secret.yaml
|
||||
|
||||
oc apply -f pat-secret.yaml -n ${USER_CHE_NAMESPACE}
|
||||
echo "======= [INFO] Personal Access Token is created. ======="
|
||||
}
|
||||
|
||||
setupSSHKeyPairs() {
|
||||
GIT_PRIVATE_KEY=$1
|
||||
GIT_PUBLIC_KEY=$2
|
||||
|
||||
echo "------- [INFO] Setup SSH Key Pairs Secret "-------
|
||||
oc project ${USER_CHE_NAMESPACE}
|
||||
ENCODED_GIT_PRIVATE_KEY=$(echo "${GIT_PRIVATE_KEY}" | base64 -w 0)
|
||||
ENCODED_GIT_PUBLIC_KEY=$(echo "${GIT_PUBLIC_KEY}" | base64 -w 0)
|
||||
cat .ci/openshift-ci/ssh-secret.yaml > ssh-secret.yaml
|
||||
|
||||
# patch the ssh-secret.yaml file
|
||||
sed -i "s#ssh_private_key#${ENCODED_GIT_PRIVATE_KEY}#g" ssh-secret.yaml
|
||||
sed -i "s#ssh_public_key#${ENCODED_GIT_PUBLIC_KEY}#g" ssh-secret.yaml
|
||||
|
||||
cat ssh-secret.yaml
|
||||
|
||||
oc apply -f ssh-secret.yaml -n ${USER_CHE_NAMESPACE}
|
||||
echo "======= [INFO] SSH Secret is created. ======="
|
||||
}
|
||||
|
||||
# Only for GitLab server administrator users
|
||||
createOAuthApplicationGitLabServer() {
|
||||
ADMIN_ACCESS_TOKEN=$1
|
||||
|
||||
CHE_URL=https://$(oc get route -n ${CHE_NAMESPACE} che -o jsonpath='{.spec.host}')
|
||||
|
||||
echo "------- [INFO] Create OAuth Application -------"
|
||||
response=$(curl -k -X POST \
|
||||
${GIT_PROVIDER_URL}/api/v4/applications \
|
||||
-H "PRIVATE-TOKEN: ${ADMIN_ACCESS_TOKEN}" \
|
||||
-d "name=${APPLICATION_NAME}" \
|
||||
-d "redirect_uri=${CHE_URL}/api/oauth/callback" \
|
||||
-d "scopes=api write_repository openid")
|
||||
|
||||
echo "------- [INFO] Response of the created OAuth Application -------"
|
||||
|
||||
OAUTH_ID=$(echo "$response" | jq -r '.id')
|
||||
APPLICATION_ID=$(echo "$response" | jq -r '.application_id')
|
||||
APPLICATION_SECRET=$(echo "$response" | jq -r '.secret')
|
||||
}
|
||||
|
||||
# Only for GitLab server administrator users
|
||||
deleteOAuthApplicationGitLabServer() {
|
||||
OAUTH_ID=$1
|
||||
ADMIN_ACCESS_TOKEN=$2
|
||||
|
||||
echo "------- [INFO] Delete OAuth Application -------"
|
||||
curl -i -k -X DELETE \
|
||||
${GIT_PROVIDER_URL}/api/v4/applications/${OAUTH_ID} \
|
||||
-H "PRIVATE-TOKEN: ${ADMIN_ACCESS_TOKEN}"
|
||||
|
||||
echo "======= [INFO] OAuth Application is deleted ======="
|
||||
}
|
||||
|
||||
# Only for GitLab server
|
||||
revokeAuthorizedOAuthApplication() {
|
||||
APPLICATION_ID=$1
|
||||
APPLICATION_SECRET=$2
|
||||
|
||||
echo "------- [INFO] Revoke authorized OAuth application -------"
|
||||
oc project ${USER_CHE_NAMESPACE}
|
||||
OAUTH_TOKEN_NAME=$(oc get secret | grep 'personal-access-token'| awk 'NR==1 { print $1 }')
|
||||
OAUTH_TOKEN=$(oc get secret $OAUTH_TOKEN_NAME -o jsonpath='{.data.token}' | base64 -d)
|
||||
|
||||
curl -i -k -X POST \
|
||||
${GIT_PROVIDER_URL}/oauth/revoke \
|
||||
-d "client_id=${APPLICATION_ID}" \
|
||||
-d "client_secret=${APPLICATION_SECRET}" \
|
||||
-d "token=${OAUTH_TOKEN}"
|
||||
|
||||
echo "======= [INFO] Authorized OAuth application is revoked ======="
|
||||
}
|
||||
|
||||
# Only for GitLab server
|
||||
setupOAuthSecret() {
|
||||
APPLICATION_ID=$1
|
||||
APPLICATION_SECRET=$2
|
||||
|
||||
echo "------- [INFO] Setup OAuth Secret -------"
|
||||
oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false
|
||||
oc project ${CHE_NAMESPACE}
|
||||
SERVER_POD=$(oc get pod -l component=che | grep "che" | awk 'NR==1 { print $1 }')
|
||||
|
||||
ENCODED_APP_ID=$(echo -n "${APPLICATION_ID}" | base64 -w 0)
|
||||
ENCODED_APP_SECRET=$(echo -n "${APPLICATION_SECRET}" | base64 -w 0)
|
||||
cat .ci/openshift-ci/oauth-secret.yaml > oauth-secret.yaml
|
||||
|
||||
# patch the oauth-secret.yaml file
|
||||
sed -i "s#git-provider-url#${GIT_PROVIDER_URL}#g" oauth-secret.yaml
|
||||
sed -i "s#encoded-application-id#${ENCODED_APP_ID}#g" oauth-secret.yaml
|
||||
sed -i "s#encoded-application-secret#${ENCODED_APP_SECRET}#g" oauth-secret.yaml
|
||||
|
||||
cat oauth-secret.yaml
|
||||
oc apply -f oauth-secret.yaml -n ${CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Wait updating deployment after create OAuth secret -------"
|
||||
oc wait --for=delete pod/${SERVER_POD} --timeout=120s
|
||||
}
|
||||
|
||||
runTestWorkspaceWithGitRepoUrl() {
|
||||
|
|
@ -196,6 +358,7 @@ runTestWorkspaceWithGitRepoUrl() {
|
|||
oc project ${OCP_USER_NAMESPACE}
|
||||
cat .ci/openshift-ci/devworkspace-test.yaml > devworkspace-test.yaml
|
||||
|
||||
echo "------- [INFO] Preparing 'devworkspace-test.yaml' and run test workspace -------"
|
||||
# patch the devworkspace-test.yaml file
|
||||
sed -i "s#ws-name#${WS_NAME}#g" devworkspace-test.yaml
|
||||
sed -i "s#project-name#${PROJECT_NAME}#g" devworkspace-test.yaml
|
||||
|
|
@ -205,7 +368,7 @@ runTestWorkspaceWithGitRepoUrl() {
|
|||
|
||||
oc apply -f devworkspace-test.yaml -n ${OCP_USER_NAMESPACE}
|
||||
oc wait -n ${OCP_USER_NAMESPACE} --for=condition=Ready dw ${WS_NAME} --timeout=360s
|
||||
echo "[INFO] Test workspace is run"
|
||||
echo "======= [INFO] Test workspace is run ======="
|
||||
}
|
||||
|
||||
testProjectIsCloned() {
|
||||
|
|
@ -214,46 +377,131 @@ testProjectIsCloned() {
|
|||
|
||||
WORKSPACE_POD_NAME=$(oc get pods -n ${OCP_USER_NAMESPACE} | grep workspace | awk '{print $1}')
|
||||
if oc exec -it -n ${OCP_USER_NAMESPACE} ${WORKSPACE_POD_NAME} -- test -f /projects/${PROJECT_NAME}/${YAML_FILE_NAME}; then
|
||||
echo "[INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} exists."
|
||||
echo "======= [INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} exists. ======="
|
||||
else
|
||||
echo "[ERROR] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} does not exist."
|
||||
echo "======= [INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} is absent. ======="
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
testGitCredentials() {
|
||||
testGitCredentialsData() {
|
||||
OCP_USER_NAMESPACE=$1
|
||||
GIT_PROVIDER_PAT=$2
|
||||
GIT_PROVIDER_URL=$3
|
||||
|
||||
echo "[INFO] Check the 'git credentials' is in a workspace"
|
||||
gitCredentials="${GIT_PROVIDER_USERNAME}:${GIT_PROVIDER_PAT}"
|
||||
echo "------- [INFO] Check the 'git credentials' is in a workspace -------"
|
||||
hostName="${GIT_PROVIDER_URL#https://}"
|
||||
|
||||
if [ "${GIT_PROVIDER_TYPE}" == "azure-devops" ]; then
|
||||
userName="username"
|
||||
else
|
||||
userName=${GIT_PROVIDER_USERNAME}
|
||||
fi
|
||||
|
||||
gitCredentials="https://${userName}:${GIT_PROVIDER_PAT}@${hostName}"
|
||||
WORKSPACE_POD_NAME=$(oc get pods -n ${OCP_USER_NAMESPACE} | grep workspace | awk '{print $1}')
|
||||
if oc exec -it -n ${OCP_USER_NAMESPACE} ${WORKSPACE_POD_NAME} -- cat /.git-credentials/credentials | grep -q ${gitCredentials}; then
|
||||
echo "[INFO] Git credentials file '/.git-credentials/credentials' exists and has the expected content."
|
||||
echo "======= [INFO] Git credentials file '/.git-credentials/credentials' exists and has the expected content. ======="
|
||||
else
|
||||
echo "[ERROR] Git credentials file '/.git-credentials/credentials' does not exist or has incorrect content."
|
||||
return 1
|
||||
echo "####### [ERROR] Git credentials file '/.git-credentials/credentials' does not exist or has incorrect content. ######
|
||||
###### Cause possible: PR code regress or service is changed. Need to investigate it. #######"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
deleteTestWorkspace() {
|
||||
WS_NAME=$1
|
||||
OCP_USER_NAMESPACE=$2
|
||||
|
||||
echo "------- [INFO] Delete test workspace -------"
|
||||
oc delete dw ${WS_NAME} -n ${OCP_USER_NAMESPACE}
|
||||
}
|
||||
|
||||
startOAuthFactoryTest() {
|
||||
CHE_URL=https://$(oc get route -n ${CHE_NAMESPACE} che -o jsonpath='{.spec.host}')
|
||||
# patch oauth-factory-test.yaml
|
||||
cat .ci/openshift-ci/pod-oauth-factory-test.yaml > oauth-factory-test.yaml
|
||||
sed -i "s#CHE_URL#${CHE_URL}#g" oauth-factory-test.yaml
|
||||
sed -i "s#CHE-NAMESPACE#${CHE_NAMESPACE}#g" oauth-factory-test.yaml
|
||||
sed -i "s#OCP_USER_NAME#${OCP_NON_ADMIN_USER_NAME}#g" oauth-factory-test.yaml
|
||||
sed -i "s#OCP_USER_PASSWORD#${OCP_LOGIN_PASSWORD}#g" oauth-factory-test.yaml
|
||||
sed -i "s#FACTORY_REPO_URL#${PRIVATE_REPO_URL}#g" oauth-factory-test.yaml
|
||||
sed -i "s#GIT_BRANCH#${GIT_REPO_BRANCH}#g" oauth-factory-test.yaml
|
||||
sed -i "s#GIT_PROVIDER_TYPE#${GIT_PROVIDER_TYPE}#g" oauth-factory-test.yaml
|
||||
sed -i "s#GIT_PROVIDER_USER_NAME#${GIT_PROVIDER_LOGIN}#g" oauth-factory-test.yaml
|
||||
sed -i "s#GIT_PROVIDER_USER_PASSWORD#${GIT_PROVIDER_PASSWORD}#g" oauth-factory-test.yaml
|
||||
|
||||
echo "------- [INFO] Applying the following patched OAuth Factory Test Pod: -------"
|
||||
cat oauth-factory-test.yaml
|
||||
echo "[INFO] --------------------------------------------------"
|
||||
oc apply -f oauth-factory-test.yaml
|
||||
# wait for the pod to start
|
||||
n=0
|
||||
while [ $n -le 120 ]
|
||||
do
|
||||
PHASE=$(oc get pod -n ${CHE_NAMESPACE} ${TEST_POD_NAME} \
|
||||
--template='{{ .status.phase }}')
|
||||
if [[ ${PHASE} == "Running" ]]; then
|
||||
echo "======= [INFO] Factory test started successfully. ======="
|
||||
return
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
n=$(( n+1 ))
|
||||
done
|
||||
|
||||
echo "####### [ERROR] Failed to start Factory test. #######
|
||||
###### Cause possible: an infrastructure problem, pod could not start, try to rerun the test. #######"
|
||||
exit 1
|
||||
}
|
||||
|
||||
startSmokeTest() {
|
||||
CHE_URL=https://$(oc get route -n ${CHE_NAMESPACE} che -o jsonpath='{.spec.host}')
|
||||
# patch che-smoke-test.yaml
|
||||
cat .ci/openshift-ci/pod-che-smoke-test.yaml > che-smoke-test.yaml
|
||||
sed -i "s#CHE_URL#${CHE_URL}#g" che-smoke-test.yaml
|
||||
sed -i "s#CHE-NAMESPACE#${CHE_NAMESPACE}#g" che-smoke-test.yaml
|
||||
sed -i "s#OCP_USER_NAME#${OCP_NON_ADMIN_USER_NAME}#g" che-smoke-test.yaml
|
||||
sed -i "s#OCP_USER_PASSWORD#${OCP_LOGIN_PASSWORD}#g" che-smoke-test.yaml
|
||||
|
||||
echo "------- [INFO] Applying the following patched Smoke Test Pod: -------"
|
||||
cat che-smoke-test.yaml
|
||||
echo "[INFO] --------------------------------------------------"
|
||||
oc apply -f che-smoke-test.yaml
|
||||
# wait for the pod to start
|
||||
n=0
|
||||
while [ $n -le 120 ]
|
||||
do
|
||||
PHASE=$(oc get pod -n ${CHE_NAMESPACE} ${TEST_POD_NAME} \
|
||||
--template='{{ .status.phase }}')
|
||||
if [[ ${PHASE} == "Running" ]]; then
|
||||
echo "======= [INFO] Smoke test started successfully. ======="
|
||||
return
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
n=$(( n+1 ))
|
||||
done
|
||||
|
||||
echo "####### [ERROR] Failed to start Smoke test. #######
|
||||
####### Cause possible: an infrastructure problem, pod could not start, try to rerun the test. #######"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Catch the finish of the job and write logs in artifacts.
|
||||
catchFinish() {
|
||||
local RESULT=$?
|
||||
killProcessByPort
|
||||
if [ "$RESULT" != "0" ]; then
|
||||
set +e
|
||||
collectEclipseCheLogs
|
||||
set -e
|
||||
fi
|
||||
|
||||
[[ "${RESULT}" != "0" ]] && echo "[ERROR] Job failed." || echo "[INFO] Job completed successfully."
|
||||
echo "------- [INFO] Terminate the process after finish the test script. -------"
|
||||
set +e
|
||||
killProcessByPort
|
||||
set -e
|
||||
|
||||
[[ "${RESULT}" != "0" ]] && echo "####### [ERROR] Job failed. #######" || echo "####### [INFO] Job completed successfully. #######"
|
||||
exit $RESULT
|
||||
}
|
||||
|
||||
|
|
@ -261,45 +509,69 @@ collectEclipseCheLogs() {
|
|||
mkdir -p ${ARTIFACTS_DIR}/che-logs
|
||||
|
||||
# Collect all Eclipse Che logs and cluster CR
|
||||
chectl server:logs -n $CHE_NAMESPACE --directory ${ARTIFACTS_DIR}/che-logs --telemetry off
|
||||
oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false
|
||||
oc get checluster -o yaml -n $CHE_NAMESPACE > "${ARTIFACTS_DIR}/che-cluster.yaml"
|
||||
chectl server:logs -n $CHE_NAMESPACE --directory ${ARTIFACTS_DIR}/che-logs --telemetry off
|
||||
}
|
||||
|
||||
testClonePublicRepoNoPatOAuth() {
|
||||
collectLogs() {
|
||||
echo "------- [INFO] Waiting until test pod finished. -------"
|
||||
oc logs -n ${CHE_NAMESPACE} ${TEST_POD_NAME} -c test -f
|
||||
sleep 3
|
||||
|
||||
# Download artifacts
|
||||
set +e
|
||||
echo -------" [INFO] Collect all Eclipse Che logs and cluster CR. -------"
|
||||
collectEclipseCheLogs
|
||||
|
||||
echo "------- [INFO] Downloading test report. -------"
|
||||
mkdir -p ${ARTIFACTS_DIR}/e2e
|
||||
oc rsync -n ${CHE_NAMESPACE} ${TEST_POD_NAME}:/tmp/e2e/report/ ${ARTIFACTS_DIR}/e2e -c download-reports
|
||||
oc exec -n ${CHE_NAMESPACE} ${TEST_POD_NAME} -c download-reports -- touch /tmp/done
|
||||
|
||||
# Revoke and delete the OAuth application
|
||||
if [[ ${TEST_POD_NAME} == "oauth-factory-test" ]]; then
|
||||
revokeAuthorizedOAuthApplication ${APPLICATION_ID} ${APPLICATION_SECRET}
|
||||
deleteOAuthApplicationGitLabServer ${OAUTH_ID} ${ADMIN_ACCESS_TOKEN}
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
EXIT_CODE=$(oc logs -n ${CHE_NAMESPACE} ${TEST_POD_NAME} -c test | grep EXIT_CODE)
|
||||
if [[ ${EXIT_CODE} != "+ EXIT_CODE=0" ]]; then
|
||||
echo "####### [ERROR] GUI test failed. Job failed. #######
|
||||
###### Cause possible: PR code regress or service is changed. Need to investigate it. #######"
|
||||
exit 1
|
||||
fi
|
||||
echo "======= [INFO] Job completed successfully. ======="
|
||||
}
|
||||
|
||||
testCloneGitRepoNoProjectExists() {
|
||||
WS_NAME=$1
|
||||
PROJECT_NAME=$2
|
||||
GIT_REPO_URL=$3
|
||||
OCP_USER_NAMESPACE=$4
|
||||
|
||||
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
|
||||
echo "------- [INFO] Check the private repository is NOT cloned with NO PAT/OAuth setup. -------"
|
||||
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} && \
|
||||
{ echo "####### [ERROR] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} should NOT be present. #######
|
||||
####### Cause possible: PR code regress or service is changed. Need to investigate it. #######" && exit 1; }
|
||||
echo "======= [INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} is NOT present. This is EXPECTED. ======="
|
||||
}
|
||||
|
||||
# Test that the repository is cloned when PAT, OAuth or SSH is configured
|
||||
testCloneGitRepoProjectShouldExists() {
|
||||
WS_NAME=$1
|
||||
PROJECT_NAME=$2
|
||||
GIT_REPO_URL=$3
|
||||
OCP_USER_NAMESPACE=$4
|
||||
|
||||
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
|
||||
echo "[INFO] Check the public repository is cloned with NO PAT/OAuth setup"
|
||||
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} || exit 1
|
||||
deleteTestWorkspace ${WS_NAME} ${OCP_USER_NAMESPACE}
|
||||
}
|
||||
|
||||
testClonePrivateRepoNoPatOAuth() {
|
||||
WS_NAME=$1
|
||||
PROJECT_NAME=$2
|
||||
GIT_REPO_URL=$3
|
||||
OCP_USER_NAMESPACE=$4
|
||||
|
||||
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
|
||||
echo "[INFO] Check the private repository is NOT cloned with NO PAT/OAuth setup"
|
||||
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} && exit 1
|
||||
deleteTestWorkspace ${WS_NAME} ${OCP_USER_NAMESPACE}
|
||||
}
|
||||
|
||||
testCloneGitRepoWithSetupPat() {
|
||||
WS_NAME=$1
|
||||
PROJECT_NAME=$2
|
||||
GIT_REPO_URL=$3
|
||||
OCP_USER_NAMESPACE=$4
|
||||
GIT_PROVIDER_PATH=$5
|
||||
|
||||
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
|
||||
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} || exit 1
|
||||
testGitCredentials ${OCP_USER_NAMESPACE} ${GIT_PROVIDER_PAT}
|
||||
deleteTestWorkspace ${WS_NAME} ${OCP_USER_NAMESPACE}
|
||||
echo "------- [INFO] Check the repository is cloned. -------"
|
||||
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} || \
|
||||
{ echo "####### [ERROR] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} should be present. #######
|
||||
###### Cause possible: PR code regress or service is changed. Need to investigate it. #######" && exit 1; }
|
||||
}
|
||||
|
||||
setupTestEnvironment() {
|
||||
|
|
@ -311,3 +583,17 @@ setupTestEnvironment() {
|
|||
forwardPortToService
|
||||
initUserNamespace ${OCP_USER_NAME}
|
||||
}
|
||||
|
||||
setupTestEnvironmentOAuthFlow() {
|
||||
ADMIN_ACCESS_TOKEN=$1
|
||||
APPLICATION_ID=$2
|
||||
APPLICATION_SECRET=$3
|
||||
|
||||
provisionOpenShiftOAuthUser
|
||||
configureGitSelfSignedCertificate
|
||||
createCustomResourcesFile
|
||||
patchCustomResourcesFile
|
||||
deployChe
|
||||
createOAuthApplicationGitLabServer ${ADMIN_ACCESS_TOKEN} ${APPLICATION_NAME}
|
||||
setupOAuthSecret ${APPLICATION_ID} ${APPLICATION_SECRET}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ metadata:
|
|||
name: ws-name
|
||||
spec:
|
||||
started: true
|
||||
routingClass: che
|
||||
template:
|
||||
projects:
|
||||
- name: project-name
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
kind: Secret
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: gitlab-oauth-secret
|
||||
namespace: eclipse-che
|
||||
labels:
|
||||
app.kubernetes.io/part-of: che.eclipse.org
|
||||
app.kubernetes.io/component: oauth-scm-configuration
|
||||
annotations:
|
||||
che.eclipse.org/oauth-scm-server: gitlab
|
||||
che.eclipse.org/scm-server-endpoint: git-provider-url
|
||||
type: Opaque
|
||||
data:
|
||||
id: encoded-application-id
|
||||
secret: encoded-application-secret
|
||||
|
|
@ -9,8 +9,7 @@ metadata:
|
|||
che.eclipse.org/che-userid: che-user-id
|
||||
che.eclipse.org/scm-personal-access-token-name: git-provider-name
|
||||
che.eclipse.org/scm-url: git-provider-url
|
||||
che.eclipse.org/scm-userid: 'git-provider-user-id'
|
||||
che.eclipse.org/scm-username: chepullreq1
|
||||
che.eclipse.org/scm-organization: ''
|
||||
data:
|
||||
token: encoded-access-token
|
||||
type: Opaque
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: che-smoke-test
|
||||
namespace: CHE-NAMESPACE
|
||||
spec:
|
||||
volumes:
|
||||
- name: test-run-results
|
||||
- name: ffmpeg-video
|
||||
- name: dshm
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
containers:
|
||||
# container containing the tests
|
||||
- name: test
|
||||
image: quay.io/eclipse/che-e2e:next
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: VIDEO_RECORDING
|
||||
value: "true"
|
||||
- name: TEST_SUITE
|
||||
value: "test"
|
||||
- name: TS_SELENIUM_EDITOR
|
||||
value: "che-code"
|
||||
- name: USERSTORY
|
||||
value: "SmokeTest"
|
||||
- name: NODE_TLS_REJECT_UNAUTHORIZED
|
||||
value: "0"
|
||||
- name: TS_SELENIUM_BASE_URL
|
||||
value: "CHE_URL"
|
||||
- name: TS_SELENIUM_LOG_LEVEL
|
||||
value: "TRACE"
|
||||
- name: TS_SELENIUM_OCP_USERNAME
|
||||
value: "OCP_USER_NAME"
|
||||
- name: TS_SELENIUM_OCP_PASSWORD
|
||||
value: "OCP_USER_PASSWORD"
|
||||
- name: TS_SELENIUM_VALUE_OPENSHIFT_OAUTH
|
||||
value: "true"
|
||||
- name: TS_OCP_LOGIN_PAGE_PROVIDER_TITLE
|
||||
value: "htpasswd"
|
||||
- name: DELETE_WORKSPACE_ON_FAILED_TEST
|
||||
value: "true"
|
||||
- name: TS_SELENIUM_START_WORKSPACE_TIMEOUT
|
||||
value: "360000"
|
||||
- name: TS_IDE_LOAD_TIMEOUT
|
||||
value: "40000"
|
||||
volumeMounts:
|
||||
- name: test-run-results
|
||||
mountPath: /tmp/e2e/report/
|
||||
- name: ffmpeg-video
|
||||
mountPath: /tmp/ffmpeg_report/
|
||||
- name: dshm
|
||||
mountPath: /dev/shm
|
||||
resources:
|
||||
requests:
|
||||
memory: "3Gi"
|
||||
cpu: "2"
|
||||
limits:
|
||||
memory: "4Gi"
|
||||
cpu: "2"
|
||||
# Download results
|
||||
- name: download-reports
|
||||
image: eeacms/rsync
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- name: test-run-results
|
||||
mountPath: /tmp/e2e/report/
|
||||
- name: ffmpeg-video
|
||||
mountPath: /tmp/ffmpeg_report/
|
||||
resources:
|
||||
command: ["sh"]
|
||||
args:
|
||||
[
|
||||
"-c",
|
||||
"while true; if [[ -f /tmp/done ]]; then exit 0; fi; do sleep 1; done",
|
||||
]
|
||||
restartPolicy: Never
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: oauth-factory-test
|
||||
namespace: CHE-NAMESPACE
|
||||
spec:
|
||||
volumes:
|
||||
- name: test-run-results
|
||||
- name: ffmpeg-video
|
||||
- name: dshm
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
containers:
|
||||
# container containing the tests
|
||||
- name: test
|
||||
image: quay.io/eclipse/che-e2e:next
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: VIDEO_RECORDING
|
||||
value: "true"
|
||||
- name: TEST_SUITE
|
||||
value: "test"
|
||||
- name: TS_SELENIUM_EDITOR
|
||||
value: "che-code"
|
||||
- name: USERSTORY
|
||||
value: "Factory"
|
||||
- name: NODE_TLS_REJECT_UNAUTHORIZED
|
||||
value: "0"
|
||||
- name: TS_SELENIUM_BASE_URL
|
||||
value: "CHE_URL"
|
||||
- name: TS_SELENIUM_LOG_LEVEL
|
||||
value: "TRACE"
|
||||
- name: TS_SELENIUM_OCP_USERNAME
|
||||
value: "OCP_USER_NAME"
|
||||
- name: TS_SELENIUM_OCP_PASSWORD
|
||||
value: "OCP_USER_PASSWORD"
|
||||
- name: TS_SELENIUM_VALUE_OPENSHIFT_OAUTH
|
||||
value: "true"
|
||||
- name: TS_SELENIUM_FACTORY_GIT_REPO_URL
|
||||
value: "FACTORY_REPO_URL"
|
||||
- name: TS_SELENIUM_FACTORY_GIT_REPO_BRANCH
|
||||
value: "GIT_BRANCH"
|
||||
- name: TS_SELENIUM_FACTORY_GIT_PROVIDER
|
||||
value: "GIT_PROVIDER_TYPE"
|
||||
- name: TS_SELENIUM_GIT_PROVIDER_OAUTH
|
||||
value: "true"
|
||||
- name: TS_SELENIUM_GIT_PROVIDER_USERNAME
|
||||
value: "GIT_PROVIDER_USER_NAME"
|
||||
- name: TS_SELENIUM_GIT_PROVIDER_PASSWORD
|
||||
value: "GIT_PROVIDER_USER_PASSWORD"
|
||||
- name: TS_OCP_LOGIN_PAGE_PROVIDER_TITLE
|
||||
value: "htpasswd"
|
||||
- name: DELETE_WORKSPACE_ON_FAILED_TEST
|
||||
value: "true"
|
||||
- name: TS_SELENIUM_START_WORKSPACE_TIMEOUT
|
||||
value: "360000"
|
||||
- name: TS_IDE_LOAD_TIMEOUT
|
||||
value: "40000"
|
||||
volumeMounts:
|
||||
- name: test-run-results
|
||||
mountPath: /tmp/e2e/report/
|
||||
- name: ffmpeg-video
|
||||
mountPath: /tmp/ffmpeg_report/
|
||||
- name: dshm
|
||||
mountPath: /dev/shm
|
||||
resources:
|
||||
requests:
|
||||
memory: "3Gi"
|
||||
cpu: "2"
|
||||
limits:
|
||||
memory: "4Gi"
|
||||
cpu: "2"
|
||||
# Download results
|
||||
- name: download-reports
|
||||
image: eeacms/rsync
|
||||
imagePullPolicy: IfNotPresent
|
||||
volumeMounts:
|
||||
- name: test-run-results
|
||||
mountPath: /tmp/e2e/report/
|
||||
- name: ffmpeg-video
|
||||
mountPath: /tmp/ffmpeg_report/
|
||||
resources:
|
||||
command: ["sh"]
|
||||
args:
|
||||
[
|
||||
"-c",
|
||||
"while true; if [[ -f /tmp/done ]]; then exit 0; fi; do sleep 1; done",
|
||||
]
|
||||
restartPolicy: Never
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: git-ssh-key
|
||||
annotations:
|
||||
controller.devfile.io/mount-as: subpath
|
||||
controller.devfile.io/mount-path: /etc/ssh/
|
||||
labels:
|
||||
controller.devfile.io/mount-to-devworkspace: "true"
|
||||
controller.devfile.io/watch-secret: "true"
|
||||
type: Opaque
|
||||
data:
|
||||
dwo_ssh_key: ssh_private_key
|
||||
dwo_ssh_key.pub: ssh_public_key
|
||||
ssh_config: aG9zdCAqCiAgSWRlbnRpdHlGaWxlIC9ldGMvc3NoL2R3b19zc2hfa2V5CiAgU3RyaWN0SG9zdEtleUNoZWNraW5nID0gbm8K
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://dev.azure.com/chepullreq1/che-pr-public/_apis/git/repositories/public-repo/items?path=/devfile.yaml"}
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_apis/git/repositories/private-repo/items?path=/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverResponse ${PUBLIC_REPO_RAW_PATH_URL} 200
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 500
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@ssh.dev.azure.com:v3/chepullreq1/che-pr-public/public-repo"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@ssh.dev.azure.com:v3/chepullreq1/che-pr-private/private-repo"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupSSHKeyPairs "${AZURE_PRIVATE_KEY}" "${AZURE_PUBLIC_KEY}"
|
||||
testFactoryResolverResponse ${PUBLIC_REPO_SSH_URL} 200
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 500
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://chepullreq1@dev.azure.com/chepullreq1/che-pr-public/_git/public-repo"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_git/private-repo"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://chepullreq1@dev.azure.com/chepullreq1/che-pr-public/_git/public-repo"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_git/private-repo"}
|
||||
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"azure-devops"}
|
||||
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://dev.azure.com"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@ssh.dev.azure.com:v3/chepullreq1/che-pr-private/private-repo"}
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_apis/git/repositories/private-repo/items?path=/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${AZURE_PAT}
|
||||
requestProvisionNamespace
|
||||
testFactoryResolverWithPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
|
||||
|
||||
echo "------- [INFO] Check clone public repository with PAT setup -------"
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testGitCredentialsData ${USER_CHE_NAMESPACE} ${AZURE_PAT} ${GIT_PROVIDER_URL}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Check clone private repository with PAT setup -------"
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testGitCredentialsData ${USER_CHE_NAMESPACE} ${AZURE_PAT} ${GIT_PROVIDER_URL}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Check clone private repository by raw devfile URL with PAT setup -------"
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
setupSSHKeyPairs "${AZURE_PRIVATE_KEY}" "${AZURE_PUBLIC_KEY}"
|
||||
|
||||
echo "------- [INFO] Check clone private repository by SSH URL with PAT setup -------"
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://bitbucket.org/chepullreq/public-repo/raw/746000bd63a54eaf8ea8aba9dfe6620e5c6c61d7/devfile.yaml"}
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://bitbucket.org/chepullreq/private-repo/raw/80b183d27c6c533462128b0c092208aad73b2906/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverNoPatOAuthRaw ${PUBLIC_REPO_RAW_PATH_URL} ${PRIVATE_REPO_RAW_PATH_URL}
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@bitbucket.org:chepullreq/public-repo.git"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@bitbucket.org:chepullreq/private-repo.git"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupSSHKeyPairs "${BITBUCKET_PRIVATE_KEY}" "${BITBUCKET_PUBLIC_KEY}"
|
||||
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_SSH_URL} ${PRIVATE_REPO_SSH_URL}
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -16,6 +16,8 @@ set -ex
|
|||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://chepullreq1@bitbucket.org/chepullreq/public-repo.git"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://chepullreq1@bitbucket.org/chepullreq/private-repo.git"}
|
||||
|
||||
|
|
@ -27,5 +29,7 @@ trap "catchFinish" EXIT SIGINT
|
|||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
|
||||
testClonePublicRepoNoPatOAuth ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testClonePrivateRepoNoPatOAuth ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2024 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export TEST_POD_NAME=${TEST_POD_NAME:-"che-smoke-test"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "collectLogs" EXIT SIGINT
|
||||
|
||||
provisionOpenShiftOAuthUser
|
||||
createCustomResourcesFile
|
||||
deployChe
|
||||
startSmokeTest
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@gitea.com:chepullreq1/public-repo.git"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@gitea.com:chepullreq1/private-repo.git"}
|
||||
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://gitea.com/chepullreq1/public-repo/raw/branch/main/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupSSHKeyPairs "${GITEA_PRIVATE_KEY}" "${GITEA_PUBLIC_KEY}"
|
||||
|
||||
testFactoryResolverResponse ${PUBLIC_REPO_SSH_URL} 200
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
|
||||
testFactoryResolverResponse ${PUBLIC_REPO_RAW_PATH_URL} 200
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_RAW_PATH_URL:-"https://${GITEA_PAT}@gitea.com/chepullreq1/private-repo/raw/branch/main/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://raw.githubusercontent.com/chepullreq1/public-repo/main/devfile.yaml"}
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://raw.githubusercontent.com/chepullreq1/private-repo/main/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverNoPatOAuthRaw ${PUBLIC_REPO_RAW_PATH_URL} ${PRIVATE_REPO_RAW_PATH_URL}
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@github.com:chepullreq1/public-repo.git"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@github.com:chepullreq1/private-repo.git"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupSSHKeyPairs "${GITHUB_PRIVATE_KEY}" "${GITHUB_PUBLIC_KEY}"
|
||||
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_SSH_URL} ${PRIVATE_REPO_SSH_URL}
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -16,6 +16,8 @@ set -ex
|
|||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://github.com/chepullreq1/public-repo.git"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://github.com/chepullreq1/private-repo.git"}
|
||||
|
||||
|
|
@ -27,5 +29,7 @@ trap "catchFinish" EXIT SIGINT
|
|||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
|
||||
testClonePublicRepoNoPatOAuth ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testClonePrivateRepoNoPatOAuth ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,14 @@ set -ex
|
|||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://github.com/chepullreq1/public-repo.git"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://github.com/chepullreq1/private-repo.git"}
|
||||
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"github"}
|
||||
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://github.com"}
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://raw.githubusercontent.com/chepullreq1/private-repo/main/devfile.yaml"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@github.com:chepullreq1/private-repo.git"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
|
|
@ -28,10 +32,28 @@ source "${SCRIPT_DIR}"/common.sh
|
|||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITHUB_USER_ID} ${GITHUB_PAT}
|
||||
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITHUB_PAT}
|
||||
requestProvisionNamespace
|
||||
testFactoryResolverWithPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
|
||||
echo "[INFO] Check clone public repository with PAT setup"
|
||||
testCloneGitRepoWithSetupPat ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE} ${GITHUB_PAT}
|
||||
echo "[INFO] Check clone private repository with PAT setup"
|
||||
testCloneGitRepoWithSetupPat ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE} ${GITHUB_PAT}
|
||||
|
||||
echo "------- [INFO] Check clone public repository with PAT setup -------"
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITHUB_PAT} ${GIT_PROVIDER_URL}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Check clone private repository with PAT setup -------"
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITHUB_PAT} ${GIT_PROVIDER_URL}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Check clone private repository by raw devfile URL with PAT setup -------"
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
setupSSHKeyPairs "${GITHUB_PRIVATE_KEY}" "${GITHUB_PUBLIC_KEY}"
|
||||
|
||||
echo "------- [INFO] Check clone private repository by SSH URL with PAT setup -------"
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://gitlab.com/chepullreq1/public-repo/-/raw/main/devfile.yaml"}
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo/-/raw/main/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverNoPatOAuthRaw ${PUBLIC_REPO_RAW_PATH_URL} ${PRIVATE_REPO_RAW_PATH_URL}
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@gitlab.com:chepullreq1/public-repo.git"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@gitlab.com:chepullreq1/private-repo.git"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupSSHKeyPairs "${GITLAB_PRIVATE_KEY}" "${GITLAB_PUBLIC_KEY}"
|
||||
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_SSH_URL} ${PRIVATE_REPO_SSH_URL}
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
@ -16,6 +16,8 @@ set -ex
|
|||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://gitlab.com/chepullreq1/public-repo.git"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo.git"}
|
||||
|
||||
|
|
@ -27,5 +29,7 @@ trap "catchFinish" EXIT SIGINT
|
|||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
|
||||
testClonePublicRepoNoPatOAuth ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testClonePrivateRepoNoPatOAuth ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# exit immediately when a command fails
|
||||
set -ex
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export TEST_POD_NAME=${TEST_POD_NAME:-"oauth-factory-test"}
|
||||
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"gitlab"}
|
||||
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://gitlab-gitlab-system.apps.git.crw-qe.com"}
|
||||
export GIT_PROVIDER_LOGIN=${GIT_PROVIDER_LOGIN:-"admin-user"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://gitlab-gitlab-system.apps.git.crw-qe.com/admin-user/private-repo.git"}
|
||||
export GIT_REPO_BRANCH=${PRIVATE_REPO_BRANCH:-"main"}
|
||||
export APPLICATION_NAME=${APPLICATION_NAME:-"TestApp"}
|
||||
export OAUTH_ID=""
|
||||
export APPLICATION_ID=""
|
||||
export APPLICATION_SECRET=""
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
source "${SCRIPT_DIR}"/common.sh
|
||||
|
||||
trap "collectLogs" EXIT SIGINT
|
||||
|
||||
setupTestEnvironmentOAuthFlow ${ADMIN_ACCESS_TOKEN} ${APPLICATION_NAME} ${APPLICATION_ID} ${APPLICATION_SECRET}
|
||||
startOAuthFactoryTest
|
||||
|
|
@ -16,10 +16,14 @@ set -ex
|
|||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
set -o pipefail
|
||||
|
||||
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
|
||||
|
||||
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://gitlab.com/chepullreq1/public-repo.git"}
|
||||
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo.git"}
|
||||
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"gitlab"}
|
||||
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://gitlab.com"}
|
||||
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@gitlab.com:chepullreq1/private-repo.git"}
|
||||
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo/-/raw/main/devfile.yaml"}
|
||||
|
||||
# import common test functions
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
|
|
@ -28,10 +32,28 @@ source "${SCRIPT_DIR}"/common.sh
|
|||
trap "catchFinish" EXIT SIGINT
|
||||
|
||||
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
|
||||
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITLAB_USER_ID} ${GITLAB_PAT}
|
||||
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITLAB_PAT}
|
||||
requestProvisionNamespace
|
||||
testFactoryResolverWithPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
|
||||
echo "[INFO] Check clone public repository with PAT setup"
|
||||
testCloneGitRepoWithSetupPat ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE} ${GITLAB_PAT}
|
||||
echo "[INFO] Check clone private repository with PAT setup"
|
||||
testCloneGitRepoWithSetupPat ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE} ${GITLAB_PAT}
|
||||
|
||||
echo "------- [INFO] Check clone public repository with PAT setup -------"
|
||||
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITLAB_PAT} ${GIT_PROVIDER_URL}
|
||||
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Check clone private repository with PAT setup -------"
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
|
||||
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITLAB_PAT} ${GIT_PROVIDER_URL}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
echo "------- [INFO] Check clone private repository by raw devfile URL with PAT setup -------"
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
||||
setupSSHKeyPairs "${GITLAB_PRIVATE_KEY}" "${GITLAB_PUBLIC_KEY}"
|
||||
|
||||
echo "------- [INFO] Check clone private repository by SSH URL with PAT setup -------"
|
||||
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
|
||||
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
|
||||
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
# Global Owners
|
||||
* @l0rd @ibuziuk @vinokurig @nickboldt @tolusha
|
||||
* @SDawley @ibuziuk @vinokurig @tolusha
|
||||
|
||||
# che.properties file is quasi-documentation, so in future we might grant access to this
|
||||
# assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/** @osslate
|
||||
|
||||
# workspace runtime infrastructure implementations
|
||||
infrastructures/** @amisevsk
|
||||
|
||||
# deploy
|
||||
deploy/** @tolusha @dkwon17
|
||||
|
|
|
|||
|
|
@ -31,23 +31,23 @@ jobs:
|
|||
cache: 'maven'
|
||||
- name: Login to docker.io
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
uses: redhat-actions/podman-login@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
registry: docker.io
|
||||
- name: Login to quay.io
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
uses: redhat-actions/podman-login@v1
|
||||
with:
|
||||
username: ${{ secrets.QUAY_USERNAME }}
|
||||
password: ${{ secrets.QUAY_PASSWORD }}
|
||||
registry: quay.io
|
||||
- name: Build with Maven
|
||||
run: mvn -B clean install -U -Pintegration
|
||||
- name: Build docker images
|
||||
- name: Build images
|
||||
if: github.event_name == 'pull_request'
|
||||
run: ./dockerfiles/build.sh --tag:${{ env.PR_IMAGE_TAG }}
|
||||
- name: Push docker images
|
||||
run: ./build/build.sh --tag:${{ env.PR_IMAGE_TAG }}
|
||||
- name: Push images
|
||||
if: github.event_name == 'pull_request'
|
||||
run: docker push quay.io/eclipse/che-server:${{ env.PR_IMAGE_TAG }}
|
||||
run: podman push quay.io/eclipse/che-server:${{ env.PR_IMAGE_TAG }}
|
||||
|
|
|
|||
|
|
@ -29,37 +29,28 @@ jobs:
|
|||
java-version: '11'
|
||||
cache: 'maven'
|
||||
- name: Login to docker.io
|
||||
uses: docker/login-action@v2
|
||||
uses: redhat-actions/podman-login@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
registry: docker.io
|
||||
- name: Login to quay.io
|
||||
uses: docker/login-action@v2
|
||||
uses: redhat-actions/podman-login@v1
|
||||
with:
|
||||
username: ${{ secrets.QUAY_USERNAME }}
|
||||
password: ${{ secrets.QUAY_PASSWORD }}
|
||||
registry: quay.io
|
||||
- name: Build with Maven
|
||||
run: mvn -B clean install -U -Pintegration
|
||||
- name: Build docker images
|
||||
- name: Build images
|
||||
id: build
|
||||
run: |
|
||||
echo "short_sha1=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
./dockerfiles/build.sh --tag:next --sha-tag
|
||||
./build/build.sh --tag:next --sha-tag
|
||||
- name: Push docker images
|
||||
run: |
|
||||
docker push quay.io/eclipse/che-endpoint-watcher:next
|
||||
docker push quay.io/eclipse/che-endpoint-watcher:${{ steps.build.outputs.short_sha1 }}
|
||||
|
||||
docker push quay.io/eclipse/che-keycloak:next
|
||||
docker push quay.io/eclipse/che-keycloak:${{ steps.build.outputs.short_sha1 }}
|
||||
|
||||
docker push quay.io/eclipse/che-postgres:next
|
||||
docker push quay.io/eclipse/che-postgres:${{ steps.build.outputs.short_sha1 }}
|
||||
|
||||
docker push quay.io/eclipse/che-server:next
|
||||
docker push quay.io/eclipse/che-server:${{ steps.build.outputs.short_sha1 }}
|
||||
podman push quay.io/eclipse/che-server:next
|
||||
podman push quay.io/eclipse/che-server:${{ steps.build.outputs.short_sha1 }}
|
||||
- name: Create failure MM message
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
# Copyright (c) 2020-2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -88,11 +88,10 @@ jobs:
|
|||
run: |
|
||||
sudo apt-get update -y || true
|
||||
# install more dependencies
|
||||
sudo apt-get -y -q install wget curl bash git
|
||||
sudo apt-get -y -q install wget curl bash git
|
||||
java -version
|
||||
|
||||
# want git >=2.24, hub >=2
|
||||
hub --version # hub reports git version too
|
||||
git --version
|
||||
gh --version
|
||||
|
||||
# want >=5
|
||||
bash --version
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
.repository/
|
||||
|
||||
# Eclipse #
|
||||
###################
|
||||
|
||||
|
|
@ -11,10 +13,6 @@ test-output/
|
|||
maven-eclipse.xml
|
||||
.factorypath
|
||||
|
||||
# Theia #
|
||||
##################
|
||||
.theia/
|
||||
|
||||
# Idea #
|
||||
##################
|
||||
*.iml
|
||||
|
|
@ -48,8 +46,6 @@ maven-eclipse.xml
|
|||
*.war
|
||||
*.ear
|
||||
|
||||
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
## Developing with Eclipse Che
|
||||
|
||||
This project contains a [devfile v2](https://github.com/eclipse-che/che-server/blob/main/devfile.yaml) located in the project's root directory.
|
||||
With this devfile you can perform the following tasks:
|
||||
|
||||
- Build project sources with maven.
|
||||
- Build a container image.
|
||||
- Push your changes to GitHub.
|
||||
|
||||
### Starting a Workspace within Eclipse Che
|
||||
|
||||
To start a new workspace within Eclipse Che, navigate to the following URL:
|
||||
|
||||
```sh
|
||||
{CHE-HOST}/#https://github.com/eclipse-che/che-server
|
||||
```
|
||||
|
||||
### Running Devfile Tasks for Downloading Dependencies and Building the Project
|
||||
|
||||
For VS Code, execute tasks defined in the devfile with these steps:
|
||||
|
||||
1. Open the command palette (Ctrl/Cmd + Shift + P).
|
||||
2. Execute the `Tasks: Run Task` command.
|
||||
3. Select the `devfile` folder and select the `1. Build sources` task to build the project sources with maven.
|
||||
4. Follow steps 1 and 2 again, select the `1. Build image` task to build a container image.
|
||||
5. In the workspace terminal, tag the **che-server** image with your account: `podman tag quay.io/eclipse/che-server:next <docker registry>/<your account>/che-server:next`.
|
||||
6. Push the **che-server** image to your account: `podman push <docker registry>/<your account>/che-server:next`.
|
||||
|
||||
# Local build requirements
|
||||
- Apache Maven 3.9 or later
|
||||
- JDK 11
|
||||
- Podman or Docker (required for running integration tests)
|
||||
A Che workspace environment allows to build the image internally, using the workspace terminal.
|
||||
|
||||
# Start and debug
|
||||
1. Deploy Che to a [Red Hat OpenShift](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-openshift-using-cli/) or [Minikube](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-minikube/) cluster by using a previously built image: `chectl server:start --platform=<openshift / minikube> --cheimage=<docker registry>/<your account>/che-server:next`.
|
||||
2. Enable local debugging of the Eclipse Che server: `chectl server:debug`.
|
||||
3. In your IDE, create a new Remote JVM Debug configuration on `localhost:8000`.
|
||||
4. Hit a breakpoint in the code and activate the debug configuration.
|
||||
|
||||
# Contributing an SCM provider
|
||||
An SCM provider support has to be provided by adding new maven modules to the wsmaster directory.
|
||||
|
||||
## Implementing che-core-api-oauth-<SCM provider name> module
|
||||
This module is responsible for Oauth requests to the SCM provider and contans next implementations:
|
||||
1. `<SCM provider name>OAuthAuthenticator` contains specific implementation of Oauth token requestand authentication endpoint.
|
||||
2. `<SCM provider name>OAuthAuthenticatorProvider` a provider of the `OAuthAuthenticator`.
|
||||
|
||||
## Implementing coresponding che-core-api-factory-<SCM provider name> module
|
||||
This module is responsible for API operations of the specific SCM provider.
|
||||
1. `<SCM provider name>ApiClient` contains all necessary HTTP API calls like `getUser()`.
|
||||
2. `<SCM provider name>AuthorisingFileContentProvider` overrides the common `AuthorisingFileContentProvider` to define the specific `isPublicRepository()` function.
|
||||
3. `<SCM provider name>FactoryParameterResolver` validates SCM URL if it corresponds to the SCM provider. Also Provides specific Factory Parameters resolver for the SCM repository.
|
||||
4. `<SCM provider name>PersonalAccessTokenFetcher` fetches Personal Access Token from the SCM provider by reqesting the OAuth API of the provider. Validates the token by comparing the token access scopes with the predefined scope list.
|
||||
5. `<SCM provider name>FileResolver` Implementation of a resolver that can return particular file content from specified SCM repository.
|
||||
6. `<SCM provider name>URLParser` Parses the string representation of the URL to an SCM specific object
|
||||
7. `<SCM provider name>UserDataFetcher` Implementation of a resolver that can return particular file content from specified SCM repository.
|
||||
|
||||
# CI
|
||||
There are several [GitHub Actions](https://github.com/eclipse-che/che-server/actions) workflows implemented for this repository:
|
||||
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/next-build.yml)
|
||||
Builds Maven artifacts, builds container images and pushes them to [quay.io](https://quay.io/organization/eclipse) on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/release.yml)
|
||||
Builds Maven artifacts and container images. Images are public and pushed to [quay.io](https://quay.io/organization/eclipse). See [RELEASE.md](https://github.com/eclipse-che/che-server/blob/master/RELEASE.md) for more information about this workflow.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/release-changelog.yml)
|
||||
Creates a GitHub release which will include a generated changelog.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/che-properties-docs-update.yml/badge.svg)
|
||||
Runs on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/build-pr-check.yml)
|
||||
Builds Maven artifacts and container images. This workflow is used as a check for all pull requests that are submitted to this project.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/sonar.yaml)
|
||||
Runs Sonar against the main branch. The result can be seen [here](https://sonarcloud.io/dashboard?id=org.eclipse.che%3Ache-server).
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/try-in-web-ide.yaml)
|
||||
Used as a check for pull requests that are submitted to this project.
|
||||
|
||||
Downstream builds can be found at the link below, which is _internal to Red Hat_. Stable builds can be found by replacing the 3.x with a specific version like 3.2.
|
||||
|
||||
- [server_3.x](https://main-jenkins-csb-crwqe.apps.ocp-c1.prod.psi.redhat.com/job/DS_CI/job/server_3.x/)
|
||||
|
||||
# Report issues
|
||||
Issues are tracked on the main Eclipse Che Repository: https://github.com/eclipse/che/issues
|
||||
51
README.md
51
README.md
|
|
@ -1,6 +1,6 @@
|
|||
# What is Che server
|
||||
Che Server provides an API for managing Kubernetes namespaces, and to retrieve devfile content from repositories,
|
||||
hosted on GitHub, GitLab, Bitbucket, and Microsoft Azure Repos.
|
||||
Che Server provides an API for managing Kubernetes namespaces and to retrieve devfile content from repositories,
|
||||
hosted on GitHub, GitLab, Bitbucket and Microsoft Azure Repos.
|
||||
|
||||
# Project structure
|
||||
Che Server is mostly a Java web application deployed on an Apache Tomcat server in a container. Che Server uses the following modules:
|
||||
|
|
@ -24,49 +24,6 @@ Che Server is mostly a Java web application deployed on an Apache Tomcat server
|
|||
|
||||
Other modules are deprecated and will be removed in the future.
|
||||
|
||||
# Build requirements
|
||||
- Apache Maven 3.6.3 or later
|
||||
- JDK 11
|
||||
- Podman or Docker (required for running integration tests)
|
||||
|
||||
# Sources build
|
||||
Run `mvn clean install` to build. Activate a faster profile build by adding `-Pfast`.
|
||||
|
||||
# Image build and push
|
||||
1. Go to the `dockerfiles` directory.
|
||||
2. Run `./build.sh`.
|
||||
3. Tag the **che-server** image with your account: `docker tag quay.io/eclipse/che-server:next <docker registry>/<your account>/che-server:next`.
|
||||
4. Push the **che-server** image to your account: `docker push <docker registry>/<your account>/che-server:next`.
|
||||
|
||||
# Debug
|
||||
1. Deploy Che to a [Red Hat OpenShift](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-openshift-using-cli/) or [Minikube](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-minikube/) cluster by using a previously built image: `chectl server:start --platform=<openshift / minikube> --cheimage=<docker registry>/<your account>/che-server:next`.
|
||||
2. Enable local debugging of the Eclipse Che server: `chectl server:debug`.
|
||||
3. In your IDE, create a new Remote JVM Debug configuration on `localhost:8000`.
|
||||
4. Hit a breakpoint in the code and activate the debug configuration.
|
||||
|
||||
|
||||
# CI
|
||||
There are several [GitHub Actions](https://github.com/eclipse-che/che-server/actions) workflows implemented for this repository:
|
||||
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/next-build.yml)
|
||||
Builds Maven artifacts, builds container images and pushes them to [quay.io](https://quay.io/organization/eclipse) on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/release.yml)
|
||||
Builds Maven artifacts and container images. Images are public and pushed to [quay.io](https://quay.io/organization/eclipse). See [RELEASE.md](https://github.com/eclipse-che/che-server/blob/master/RELEASE.md) for more information about this workflow.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/release-changelog.yml)
|
||||
Creates a GitHub release which will include a generated changelog.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/che-properties-docs-update.yml/badge.svg)
|
||||
Runs on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/build-pr-check.yml)
|
||||
Builds Maven artifacts and container images. This workflow is used as a check for all pull requests that are submitted to this project.
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/sonar.yaml)
|
||||
Runs Sonar against the main branch. The result can be seen [here](https://sonarcloud.io/dashboard?id=org.eclipse.che%3Ache-server).
|
||||
- [](https://github.com/eclipse-che/che-server/actions/workflows/try-in-web-ide.yaml)
|
||||
Used as a check for pull requests that are submitted to this project.
|
||||
|
||||
Downstream builds can be found at the link below, which is _internal to Red Hat_. Stable builds can be found by replacing the 3.x with a specific version like 3.2.
|
||||
|
||||
- [server_3.x](https://main-jenkins-csb-crwqe.apps.ocp-c1.prod.psi.redhat.com/job/DS_CI/job/server_3.x/)
|
||||
|
||||
# License
|
||||
|
||||
- [Eclipse Public License 2.0](LICENSE)
|
||||
|
|
@ -76,6 +33,6 @@ Downstream builds can be found at the link below, which is _internal to Red Hat_
|
|||
The Eclipse Che community is globally reachable through public chat rooms, mailing list and weekly calls.
|
||||
See the Eclipse Che Documentation about [how you can join our community](https://www.eclipse.org/che/docs/stable/overview/introduction-to-eclipse-che/#_joining_the_community).
|
||||
|
||||
## Report issues
|
||||
## Builds
|
||||
|
||||
Issues are tracked on the main Eclipse Che Repository: https://github.com/eclipse/che/issues
|
||||
* [](https://github.com/eclipse-che/che-server/actions/workflows/release.yml)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-assembly-parent</artifactId>
|
||||
<groupId>org.eclipse.che</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>assembly-che-tomcat</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-assembly-parent</artifactId>
|
||||
<groupId>org.eclipse.che</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>assembly-main</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-assembly-parent</artifactId>
|
||||
<groupId>org.eclipse.che</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>assembly-root-war</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-assembly-parent</artifactId>
|
||||
<groupId>org.eclipse.che</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>assembly-swagger-war</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-assembly-parent</artifactId>
|
||||
<groupId>org.eclipse.che</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>assembly-wsmaster-war</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
|
@ -91,10 +91,6 @@
|
|||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-account</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-auth</artifactId>
|
||||
|
|
@ -107,6 +103,10 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-auth-bitbucket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-auth-github</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-auth-gitlab</artifactId>
|
||||
|
|
@ -155,10 +155,6 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-logger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-metrics</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-ssh</artifactId>
|
||||
|
|
@ -195,18 +191,6 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-schedule</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db-vendor-h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db-vendor-postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-logback</artifactId>
|
||||
|
|
@ -351,10 +335,6 @@
|
|||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-integration-guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jgroups</groupId>
|
||||
<artifactId>jgroups</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -26,7 +26,6 @@ import io.jsonwebtoken.JwtParser;
|
|||
import io.jsonwebtoken.SigningKeyResolver;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.eclipse.che.api.core.notification.RemoteSubscriptionStorage;
|
||||
import org.eclipse.che.api.core.rest.CheJsonProvider;
|
||||
import org.eclipse.che.api.core.rest.MessageBodyAdapter;
|
||||
|
|
@ -36,6 +35,7 @@ import org.eclipse.che.api.factory.server.FactoryAcceptValidator;
|
|||
import org.eclipse.che.api.factory.server.FactoryCreateValidator;
|
||||
import org.eclipse.che.api.factory.server.FactoryEditValidator;
|
||||
import org.eclipse.che.api.factory.server.FactoryParametersResolver;
|
||||
import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver;
|
||||
import org.eclipse.che.api.factory.server.ScmFileResolver;
|
||||
import org.eclipse.che.api.factory.server.ScmService;
|
||||
import org.eclipse.che.api.factory.server.azure.devops.AzureDevOpsFactoryParametersResolver;
|
||||
|
|
@ -47,11 +47,11 @@ import org.eclipse.che.api.factory.server.bitbucket.BitbucketServerScmFileResolv
|
|||
import org.eclipse.che.api.factory.server.git.ssh.GitSshFactoryParametersResolver;
|
||||
import org.eclipse.che.api.factory.server.git.ssh.GitSshScmFileResolver;
|
||||
import org.eclipse.che.api.factory.server.github.GithubFactoryParametersResolver;
|
||||
import org.eclipse.che.api.factory.server.github.GithubFactoryParametersResolverSecond;
|
||||
import org.eclipse.che.api.factory.server.github.GithubScmFileResolver;
|
||||
import org.eclipse.che.api.factory.server.github.GithubScmFileResolverSecond;
|
||||
import org.eclipse.che.api.factory.server.gitlab.GitlabFactoryParametersResolver;
|
||||
import org.eclipse.che.api.factory.server.gitlab.GitlabScmFileResolver;
|
||||
import org.eclipse.che.api.factory.server.scm.OAuthTokenFetcher;
|
||||
import org.eclipse.che.api.metrics.WsMasterMetricsModule;
|
||||
import org.eclipse.che.api.system.server.ServiceTermination;
|
||||
import org.eclipse.che.api.system.server.SystemModule;
|
||||
import org.eclipse.che.api.user.server.NotImplementedTokenValidator;
|
||||
|
|
@ -84,13 +84,10 @@ import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceNameEnvVa
|
|||
import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceNamespaceNameEnvVarProvider;
|
||||
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
|
||||
import org.eclipse.che.commons.observability.deploy.ExecutorWrapperModule;
|
||||
import org.eclipse.che.core.db.DBTermination;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializer;
|
||||
import org.eclipse.che.core.tracing.metrics.TracingMetricsModule;
|
||||
import org.eclipse.che.inject.DynaModule;
|
||||
import org.eclipse.che.multiuser.api.authentication.commons.token.HeaderRequestTokenExtractor;
|
||||
import org.eclipse.che.multiuser.api.authentication.commons.token.RequestTokenExtractor;
|
||||
import org.eclipse.che.multiuser.api.permission.server.AdminPermissionInitializer;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.server.PermissionCheckerImpl;
|
||||
import org.eclipse.che.multiuser.api.workspace.activity.MultiUserWorkspaceActivityModule;
|
||||
|
|
@ -104,7 +101,6 @@ import org.eclipse.che.multiuser.permission.user.UserServicePermissionsFilter;
|
|||
import org.eclipse.che.security.PBKDF2PasswordEncryptor;
|
||||
import org.eclipse.che.security.PasswordEncryptor;
|
||||
import org.eclipse.che.security.oauth.EmbeddedOAuthAPI;
|
||||
import org.eclipse.che.security.oauth.GitLabModule;
|
||||
import org.eclipse.che.security.oauth.OAuthAPI;
|
||||
import org.eclipse.che.security.oauth.OpenShiftOAuthModule;
|
||||
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientConfigFactory;
|
||||
|
|
@ -126,7 +122,6 @@ import org.eclipse.che.workspace.infrastructure.openshift.OpenShiftInfrastructur
|
|||
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
|
||||
import org.eclipse.che.workspace.infrastructure.openshift.multiuser.oauth.KeycloakProviderConfigFactory;
|
||||
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||
import org.flywaydb.core.internal.util.PlaceholderReplacer;
|
||||
|
||||
/** @author andrew00x */
|
||||
@DynaModule
|
||||
|
|
@ -142,18 +137,10 @@ public class WsMasterModule extends AbstractModule {
|
|||
}
|
||||
|
||||
// db related components modules
|
||||
install(new org.eclipse.che.account.api.AccountModule());
|
||||
install(new org.eclipse.che.api.ssh.server.jpa.SshJpaModule());
|
||||
install(new org.eclipse.che.api.core.jsonrpc.impl.JsonRpcModule());
|
||||
install(new org.eclipse.che.api.core.websocket.impl.WebSocketModule());
|
||||
|
||||
// db configuration
|
||||
bind(SchemaInitializer.class)
|
||||
.to(org.eclipse.che.core.db.schema.impl.flyway.FlywaySchemaInitializer.class);
|
||||
bind(org.eclipse.che.core.db.DBInitializer.class).asEagerSingleton();
|
||||
bind(PlaceholderReplacer.class)
|
||||
.toProvider(org.eclipse.che.core.db.schema.impl.flyway.PlaceholderReplacerProvider.class);
|
||||
|
||||
// factory
|
||||
bind(FactoryAcceptValidator.class)
|
||||
.to(org.eclipse.che.api.factory.server.impl.FactoryAcceptValidatorImpl.class);
|
||||
|
|
@ -169,6 +156,9 @@ public class WsMasterModule extends AbstractModule {
|
|||
Multibinder<FactoryParametersResolver> factoryParametersResolverMultibinder =
|
||||
Multibinder.newSetBinder(binder(), FactoryParametersResolver.class);
|
||||
factoryParametersResolverMultibinder.addBinding().to(GithubFactoryParametersResolver.class);
|
||||
factoryParametersResolverMultibinder
|
||||
.addBinding()
|
||||
.to(GithubFactoryParametersResolverSecond.class);
|
||||
factoryParametersResolverMultibinder
|
||||
.addBinding()
|
||||
.to(BitbucketServerAuthorizingFactoryParametersResolver.class);
|
||||
|
|
@ -177,11 +167,15 @@ public class WsMasterModule extends AbstractModule {
|
|||
factoryParametersResolverMultibinder
|
||||
.addBinding()
|
||||
.to(AzureDevOpsFactoryParametersResolver.class);
|
||||
factoryParametersResolverMultibinder
|
||||
.addBinding()
|
||||
.to(RawDevfileUrlFactoryParameterResolver.class);
|
||||
factoryParametersResolverMultibinder.addBinding().to(GitSshFactoryParametersResolver.class);
|
||||
|
||||
Multibinder<ScmFileResolver> scmFileResolverResolverMultibinder =
|
||||
Multibinder.newSetBinder(binder(), ScmFileResolver.class);
|
||||
scmFileResolverResolverMultibinder.addBinding().to(GithubScmFileResolver.class);
|
||||
scmFileResolverResolverMultibinder.addBinding().to(GithubScmFileResolverSecond.class);
|
||||
scmFileResolverResolverMultibinder.addBinding().to(BitbucketScmFileResolver.class);
|
||||
scmFileResolverResolverMultibinder.addBinding().to(GitlabScmFileResolver.class);
|
||||
scmFileResolverResolverMultibinder.addBinding().to(BitbucketServerScmFileResolver.class);
|
||||
|
|
@ -205,9 +199,7 @@ public class WsMasterModule extends AbstractModule {
|
|||
install(new DevfileModule());
|
||||
|
||||
bind(WorkspaceEntityProvider.class);
|
||||
bind(org.eclipse.che.api.workspace.server.TemporaryWorkspaceRemover.class);
|
||||
bind(org.eclipse.che.api.workspace.server.WorkspaceService.class);
|
||||
bind(org.eclipse.che.api.devfile.server.DevfileService.class);
|
||||
bind(org.eclipse.che.api.devfile.server.UserDevfileEntityProvider.class);
|
||||
|
||||
install(new FactoryModuleBuilder().build(ServersCheckerFactory.class));
|
||||
|
|
@ -274,10 +266,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
terminationMultiBinder
|
||||
.addBinding()
|
||||
.to(org.eclipse.che.api.system.server.CronThreadPullTermination.class);
|
||||
terminationMultiBinder
|
||||
.addBinding()
|
||||
.to(org.eclipse.che.api.workspace.server.hc.probe.ProbeSchedulerTermination.class);
|
||||
bind(DBTermination.class);
|
||||
|
||||
final Map<String, String> persistenceProperties = new HashMap<>();
|
||||
persistenceProperties.put(PersistenceUnitProperties.TARGET_SERVER, "None");
|
||||
|
|
@ -293,8 +281,9 @@ public class WsMasterModule extends AbstractModule {
|
|||
install(new FactoryModuleBuilder().build(PassThroughProxyProvisionerFactory.class));
|
||||
installDefaultSecureServerExposer(infrastructure);
|
||||
install(new org.eclipse.che.security.BitbucketModule());
|
||||
install(new GitLabModule());
|
||||
install(new org.eclipse.che.security.oauth.GitLabModule());
|
||||
install(new org.eclipse.che.security.oauth.AzureDevOpsModule());
|
||||
install(new org.eclipse.che.security.oauth.GithubModule());
|
||||
|
||||
configureMultiUserMode(persistenceProperties, infrastructure);
|
||||
|
||||
|
|
@ -319,7 +308,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
}
|
||||
if (Boolean.valueOf(System.getenv("CHE_METRICS_ENABLED"))) {
|
||||
install(new org.eclipse.che.core.metrics.MetricsModule());
|
||||
install(new WsMasterMetricsModule());
|
||||
install(new InfrastructureMetricsModule());
|
||||
} else {
|
||||
install(new org.eclipse.che.core.metrics.NoopMetricsModule());
|
||||
|
|
@ -360,9 +348,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
persistenceProperties.put(
|
||||
PersistenceUnitProperties.EXCEPTION_HANDLER_CLASS,
|
||||
"org.eclipse.che.core.db.postgresql.jpa.eclipselink.PostgreSqlExceptionHandler");
|
||||
bind(DataSource.class).toProvider(org.eclipse.che.core.db.JndiDataSourceProvider.class);
|
||||
|
||||
install(new org.eclipse.che.multiuser.api.permission.server.jpa.SystemPermissionsJpaModule());
|
||||
|
||||
install(
|
||||
new org.eclipse.che.multiuser.permission.workspace.server.WorkspaceApiPermissionsModule());
|
||||
|
|
@ -409,10 +394,8 @@ public class WsMasterModule extends AbstractModule {
|
|||
bind(TokenValidator.class).to(NotImplementedTokenValidator.class);
|
||||
bind(ProfileDao.class).to(JpaProfileDao.class);
|
||||
bind(OAuthAPI.class).to(EmbeddedOAuthAPI.class).asEagerSingleton();
|
||||
bind(OAuthTokenFetcher.class).to(EmbeddedOAuthAPI.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
bind(AdminPermissionInitializer.class).asEagerSingleton();
|
||||
install(new MachineAuthModule());
|
||||
|
||||
// User and profile - use profile from keycloak and other stuff is JPA
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
# Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -91,10 +91,6 @@ che.workspace.server.liveness_probes=wsagent/http,exec-agent/http,terminal,theia
|
|||
# The default is: 10MB=10485760.
|
||||
che.workspace.startup_debug_log_limit_bytes=10485760
|
||||
|
||||
# If set to `true`, 'stop-workspace' role with the edit privileges is granted to the 'che' ServiceAccount if OpenShift OAuth is enabled.
|
||||
# This configuration is mainly required for workspace idling when the OpenShift OAuth is enabled.
|
||||
che.workspace.stop.role.enabled=true
|
||||
|
||||
# Specifies whether {prod-short} is deployed with DevWorkspaces enabled.
|
||||
# This property is set by the {prod-short} Operator if it also installed the support for DevWorkspaces.
|
||||
# This property is used to advertise this fact to the {prod-short} dashboard.
|
||||
|
|
@ -145,22 +141,42 @@ che.oauth.azure.devops.redirecturis=https://${CHE_HOST}/api/oauth/callback
|
|||
# Location of the file with GitHub client id.
|
||||
che.oauth2.github.clientid_filepath=NULL
|
||||
|
||||
# Configuration of the GitHub OAuth2 client. Used to obtain personal access tokens.
|
||||
# Location of the file with GitHub client id (The second GitHub instance).
|
||||
che.oauth2.github.clientid_filepath_2=NULL
|
||||
|
||||
# Location of the file with GitHub client secret.
|
||||
che.oauth2.github.clientsecret_filepath=NULL
|
||||
|
||||
# Location of the file with GitHub client secret (The second GitHub instance).
|
||||
che.oauth2.github.clientsecret_filepath_2=NULL
|
||||
|
||||
# GitHub OAuth authorization URI.
|
||||
che.oauth.github.authuri= https://github.com/login/oauth/authorize
|
||||
|
||||
# GitHub OAuth authorization URI (The second GitHub instance).
|
||||
che.oauth.github.authuri_2= https://github.com/login/oauth/authorize
|
||||
|
||||
# GitHub OAuth token URI.
|
||||
che.oauth.github.tokenuri= https://github.com/login/oauth/access_token
|
||||
|
||||
# GitHub OAuth token URI (The second GitHub instance).
|
||||
che.oauth.github.tokenuri_2= https://github.com/login/oauth/access_token
|
||||
|
||||
# GitHub server address.
|
||||
# Prerequisite: OAuth 2 integration is configured on the GitHub server.
|
||||
che.integration.github.oauth_endpoint=NULL
|
||||
|
||||
# GitHub server address.
|
||||
# Prerequisite: OAuth 2 integration is configured on the GitHub server (The second GitHub instance).
|
||||
che.integration.github.oauth_endpoint_2=NULL
|
||||
|
||||
# GitHub server disable subdomain isolation flag.
|
||||
che.integration.github.disable_subdomain_isolation=false
|
||||
|
||||
# GitHub server disable subdomain isolation flag (The second GitHub instance).
|
||||
che.integration.github.disable_subdomain_isolation_2=false
|
||||
|
||||
# GitHub OAuth redirect URIs.
|
||||
# Separate multiple values with comma, for example: URI,URI,URI.
|
||||
che.oauth.github.redirecturis= http://localhost:${CHE_PORT}/api/oauth/callback
|
||||
|
|
@ -643,3 +659,16 @@ che.oauth2.gitlab.clientid_filepath=NULL
|
|||
|
||||
# Location of the file with GitLab client secret.
|
||||
che.oauth2.gitlab.clientsecret_filepath=NULL
|
||||
|
||||
### Advanced authorization
|
||||
# Comma separated list of users allowed to access Che.
|
||||
che.infra.kubernetes.advanced_authorization.allow_users=NULL
|
||||
|
||||
# Comma separated list of groups of users allowed to access Che.
|
||||
che.infra.kubernetes.advanced_authorization.allow_groups=NULL
|
||||
|
||||
# Comma separated list of users denied to access Che.
|
||||
che.infra.kubernetes.advanced_authorization.deny_users=NULL
|
||||
|
||||
# Comma separated list of groups of users denied to access Che.
|
||||
che.infra.kubernetes.advanced_authorization.deny_groups=NULL
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -37,6 +37,7 @@ import org.reflections.scanners.FieldAnnotationsScanner;
|
|||
import org.reflections.scanners.MethodAnnotationsScanner;
|
||||
import org.reflections.scanners.MethodParameterScanner;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Ignore;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class IntegrityConfigurationTest {
|
||||
|
|
@ -125,6 +126,7 @@ public class IntegrityConfigurationTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void shouldNotDeclareUnused() {
|
||||
Reflections reflections =
|
||||
new Reflections(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-server</artifactId>
|
||||
<groupId>org.eclipse.che</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>che-assembly-parent</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
# Copyright (c) 2017 Red Hat, Inc.
|
||||
#
|
||||
# Copyright (c) 2017-2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -14,6 +15,7 @@ IMAGE_ALIASES=${IMAGE_ALIASES:-}
|
|||
ERROR=${ERROR:-}
|
||||
DIR=${DIR:-}
|
||||
SHA_TAG=${SHA_TAG:-}
|
||||
BUILDER=${BUILDER:-}
|
||||
|
||||
skip_tests() {
|
||||
if [ $SKIP_TESTS = "true" ]; then
|
||||
|
|
@ -48,6 +50,7 @@ init() {
|
|||
ARGS=""
|
||||
OPTIONS=""
|
||||
DOCKERFILE=""
|
||||
BUILD_COMMAND="build"
|
||||
BUILD_ARGS=""
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
|
|
@ -103,6 +106,37 @@ build() {
|
|||
DIR=$(cd "$(dirname "$0")"; pwd)
|
||||
fi
|
||||
|
||||
BUILD_COMAMAND="build"
|
||||
if [ -z $BUILDER ]; then
|
||||
echo "BUILDER is not specified, trying with podman"
|
||||
BUILDER=$(command -v podman || true)
|
||||
if [[ ! -x $BUILDER ]]; then
|
||||
echo "[WARNING] podman is not installed, trying with buildah"
|
||||
BUILDER=$(command -v buildah || true)
|
||||
if [[ ! -x $BUILDER ]]; then
|
||||
echo "[WARNING] buildah is not installed, trying with docker"
|
||||
BUILDER=$(command -v docker || true)
|
||||
if [[ ! -x $BUILDER ]]; then
|
||||
echo "[ERROR] This script requires podman, buildah or docker to be installed. Must abort!"; exit 1
|
||||
fi
|
||||
else
|
||||
BUILD_COMMAND="bud"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [[ ! -x $(command -v "$BUILDER" || true) ]]; then
|
||||
echo "Builder $BUILDER is missing. Aborting."; exit 1
|
||||
fi
|
||||
if [[ $BUILDER =~ "docker" || $BUILDER =~ "podman" ]]; then
|
||||
if [[ ! $($BUILDER ps) ]]; then
|
||||
echo "Builder $BUILDER is not functioning. Aborting."; exit 1
|
||||
fi
|
||||
fi
|
||||
if [[ $BUILDER =~ "buildah" ]]; then
|
||||
BUILD_COMMAND="bud"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If Dockerfile is empty, build all Dockerfiles
|
||||
if [ -z ${DOCKERFILE} ]; then
|
||||
DOCKERFILES_TO_BUILD="$(ls ${DIR}/Dockerfile*)"
|
||||
|
|
@ -137,26 +171,26 @@ build_image() {
|
|||
-e "s;\${BUILD_PREFIX};${PREFIX};" \
|
||||
-e "s;\${BUILD_TAG};${TAG};" \
|
||||
> ${DIR}/.Dockerfile
|
||||
cd "${DIR}" && docker build -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} .
|
||||
cd "${DIR}" && "${BUILDER}" "${BUILD_COMMAND}" -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} .
|
||||
DOCKER_BUILD_STATUS=$?
|
||||
rm ${DIR}/.Dockerfile
|
||||
if [ $DOCKER_BUILD_STATUS -eq 0 ]; then
|
||||
printf "Build of ${BLUE}${IMAGE_NAME} ${GREEN}[OK]${NC}\n"
|
||||
if [ ! -z "${SHA_TAG}" ]; then
|
||||
SHA_IMAGE_NAME=${ORGANIZATION}/${PREFIX}-${NAME}:${SHA_TAG}
|
||||
docker tag ${IMAGE_NAME} ${SHA_IMAGE_NAME}
|
||||
"${BUILDER}" tag ${IMAGE_NAME} ${SHA_IMAGE_NAME}
|
||||
DOCKER_TAG_STATUS=$?
|
||||
if [ $DOCKER_TAG_STATUS -eq 0 ]; then
|
||||
printf "Re-tagging with SHA based tag ${BLUE}${SHA_IMAGE_NAME} ${GREEN}[OK]${NC}\n"
|
||||
else
|
||||
printf "${RED}Failure when tagging docker image ${SHA_IMAGE_NAME}${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "${IMAGE_ALIASES}" ]; then
|
||||
for TMP_IMAGE_NAME in ${IMAGE_ALIASES}
|
||||
do
|
||||
docker tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG}
|
||||
"${BUILDER}" tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG}
|
||||
DOCKER_TAG_STATUS=$?
|
||||
if [ $DOCKER_TAG_STATUS -eq 0 ]; then
|
||||
printf " /alias ${BLUE}${TMP_IMAGE_NAME}:${TAG}${NC} ${GREEN}[OK]${NC}\n"
|
||||
|
|
@ -174,32 +208,6 @@ build_image() {
|
|||
fi
|
||||
}
|
||||
|
||||
check_docker() {
|
||||
if ! docker ps > /dev/null 2>&1; then
|
||||
output=$(docker ps)
|
||||
printf "${RED}Docker not installed properly: ${output}${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
docker_exec() {
|
||||
if has_docker_for_windows_client; then
|
||||
MSYS_NO_PATHCONV=1 docker.exe "$@"
|
||||
else
|
||||
"$(which docker)" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
has_docker_for_windows_client() {
|
||||
GLOBAL_HOST_ARCH=$(docker version --format {{.Client}})
|
||||
|
||||
if [[ "${GLOBAL_HOST_ARCH}" = *"windows"* ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_full_path() {
|
||||
echo "$(cd "$(dirname "${1}")"; pwd)/$(basename "$1")"
|
||||
}
|
||||
|
|
@ -227,3 +235,27 @@ get_mount_path() {
|
|||
CLEAN_PATH=$(get_clean_path "${POSIX_PATH}")
|
||||
echo $CLEAN_PATH
|
||||
}
|
||||
|
||||
# grab assembly
|
||||
DIR="$(cd "$(dirname "$0")"; pwd)/dockerfiles"
|
||||
if [ ! -d "${DIR}/../../assembly/assembly-main/target" ]; then
|
||||
echo "${ERROR}Have you built assembly/assemby-main in ${DIR}/../assembly/assembly-main 'mvn clean install'?"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Use of folder
|
||||
BUILD_ASSEMBLY_DIR=$(echo "${DIR}"/../../assembly/assembly-main/target/eclipse-che-*/eclipse-che-*/)
|
||||
LOCAL_ASSEMBLY_DIR="${DIR}"/eclipse-che
|
||||
|
||||
if [ -d "${LOCAL_ASSEMBLY_DIR}" ]; then
|
||||
rm -r "${LOCAL_ASSEMBLY_DIR}"
|
||||
fi
|
||||
|
||||
echo "Copying assembly ${BUILD_ASSEMBLY_DIR} --> ${LOCAL_ASSEMBLY_DIR}"
|
||||
cp -r "${BUILD_ASSEMBLY_DIR}" "${LOCAL_ASSEMBLY_DIR}"
|
||||
|
||||
init --name:server "$@"
|
||||
build
|
||||
|
||||
#cleanUp
|
||||
rm -rf ${DIR}/eclipse-che
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
|
||||
# https://access.redhat.com/containers/?tab=tags#/registry.access.redhat.com/ubi8-minimal
|
||||
FROM registry.access.redhat.com/ubi8-minimal:8.8-1037
|
||||
FROM registry.access.redhat.com/ubi8-minimal:8.9-1161
|
||||
USER root
|
||||
ENV CHE_HOME=/home/user/eclipse-che
|
||||
ENV JAVA_HOME=/usr/lib/jvm/jre
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright (c) 2018-2023 Red Hat, Inc.
|
||||
# This program and the accompanying materials are made
|
||||
# available under the terms of the Eclipse Public License 2.0
|
||||
# which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
# Contributors:
|
||||
# Red Hat, Inc. - initial API and implementation
|
||||
#
|
||||
|
||||
# https://access.redhat.com/containers/?tab=tags#/registry.access.redhat.com/ubi8-minimal
|
||||
FROM ubi8-minimal:8.9-1161
|
||||
USER root
|
||||
ENV CHE_HOME=/home/user/devspaces
|
||||
ENV JAVA_HOME=/usr/lib/jvm/jre
|
||||
RUN microdnf install java-11-openjdk-headless tar gzip shadow-utils findutils && \
|
||||
microdnf update -y && \
|
||||
microdnf -y clean all && rm -rf /var/cache/yum && echo "Installed Packages" && rpm -qa | sort -V && echo "End Of Installed Packages" && \
|
||||
adduser -G root user && mkdir -p /home/user/devspaces
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
||||
# see fetch-artifacts-pnc.yaml
|
||||
COPY artifacts/assembly-main.tar.gz /tmp/assembly-main.tar.gz
|
||||
RUN tar xzf /tmp/assembly-main.tar.gz --strip-components=1 -C /home/user/devspaces; rm -f /tmp/assembly-main.tar.gz
|
||||
|
||||
# this should fail if the startup script is not found in correct path /home/user/devspaces/tomcat/bin/catalina.sh
|
||||
RUN mkdir /logs /data && \
|
||||
chmod 0777 /logs /data && \
|
||||
chgrp -R 0 /home/user /logs /data && \
|
||||
chown -R user /home/user && \
|
||||
chmod -R g+rwX /home/user && \
|
||||
find /home/user -type d -exec chmod 777 {} \; && \
|
||||
java -version && echo -n "Server startup script in: " && \
|
||||
find /home/user/devspaces -name catalina.sh | grep -z /home/user/devspaces/tomcat/bin/catalina.sh
|
||||
|
||||
USER user
|
||||
|
||||
# append Brew metadata here
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -11,7 +11,10 @@
|
|||
*/
|
||||
package org.eclipse.che.api.core.rest;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
|
@ -19,6 +22,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
|
|||
import jakarta.ws.rs.ext.Provider;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
|
|
@ -42,11 +46,18 @@ public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException>
|
|||
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
final String utcTime = dateFormat.format(new Date());
|
||||
final String errorMessage = format("Internal Server Error occurred, error time: %s", utcTime);
|
||||
String message = exception.getMessage();
|
||||
final String errorMessage =
|
||||
isNullOrEmpty(message)
|
||||
? format("Internal Server Error occurred, error time: %s", utcTime)
|
||||
: message;
|
||||
|
||||
LOG.error(errorMessage, exception);
|
||||
|
||||
ServiceError serviceError = DtoFactory.newDto(ServiceError.class).withMessage(errorMessage);
|
||||
List<String> trace =
|
||||
stream(exception.getStackTrace()).map(StackTraceElement::toString).collect(toList());
|
||||
ServiceError serviceError =
|
||||
DtoFactory.newDto(ServiceError.class).withMessage(errorMessage).withTrace(trace);
|
||||
return Response.serverError()
|
||||
.entity(DtoFactory.getInstance().toJson(serviceError))
|
||||
.type(MediaType.APPLICATION_JSON)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
package org.eclipse.che.api.core.rest.shared.dto;
|
||||
|
||||
import java.util.List;
|
||||
import org.eclipse.che.dto.shared.DTO;
|
||||
|
||||
/**
|
||||
|
|
@ -30,8 +31,12 @@ public interface ServiceError {
|
|||
*/
|
||||
String getMessage();
|
||||
|
||||
List<String> getTrace();
|
||||
|
||||
ServiceError withMessage(String message);
|
||||
|
||||
ServiceError withTrace(List<String> trace);
|
||||
|
||||
/**
|
||||
* Set error message.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-dto-maven-plugin</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-dto</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
<version>7.86.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-api-model</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<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>
|
||||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-db-vendor-h2</artifactId>
|
||||
<name>Che Core :: Commons :: DB :: Vendor H2</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>jakarta.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.h2.jpa.eclipselink;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
|
||||
import org.eclipse.che.core.db.jpa.IntegrityConstraintViolationException;
|
||||
import org.eclipse.persistence.exceptions.DatabaseException;
|
||||
import org.eclipse.persistence.exceptions.ExceptionHandler;
|
||||
|
||||
/**
|
||||
* Rethrows vendor specific exceptions as common exceptions. See <a
|
||||
* href="http://www.h2database.com/javadoc/org/h2/api/ErrorCode.html">H2 error codes</a>.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class H2ExceptionHandler implements ExceptionHandler {
|
||||
|
||||
public Object handleException(RuntimeException exception) {
|
||||
if (exception instanceof DatabaseException && exception.getCause() instanceof SQLException) {
|
||||
final SQLException sqlEx = (SQLException) exception.getCause();
|
||||
switch (sqlEx.getErrorCode()) {
|
||||
case 23505:
|
||||
throw new DuplicateKeyException(exception.getMessage(), exception);
|
||||
case 23506:
|
||||
throw new IntegrityConstraintViolationException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.h2.jpa.eclipselink;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
|
||||
import org.eclipse.che.core.db.JNDIDataSourceFactory;
|
||||
|
||||
public class H2SQLJndiDataSourceFactory extends JNDIDataSourceFactory {
|
||||
|
||||
private static final String DEFAULT_USERNAME = "username";
|
||||
private static final String DEFAULT_PASSWORD = "password";
|
||||
private static final String DEFAULT_URL = "jdbc:h2:file:/data/h2";
|
||||
private static final String DEFAULT_DRIVER__CLASS__NAME = "org.h2.Driver";
|
||||
private static final String DEFAULT_MAX__TOTAL = "20";
|
||||
private static final String DEFAULT_MAX__IDLE = "2";
|
||||
private static final String DEFAULT_MAX__WAIT__MILLIS = "-1";
|
||||
|
||||
public H2SQLJndiDataSourceFactory() throws Exception {
|
||||
super(
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_USERNAME")), DEFAULT_USERNAME),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_PASSWORD")), DEFAULT_PASSWORD),
|
||||
firstNonNull(nullStringToNullReference(System.getenv("CHE_JDBC_H2_URL")), DEFAULT_URL),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_DRIVER__CLASS__NAME")),
|
||||
DEFAULT_DRIVER__CLASS__NAME),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__TOTAL")), DEFAULT_MAX__TOTAL),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__IDLE")), DEFAULT_MAX__IDLE),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__WAIT__MILLIS")),
|
||||
DEFAULT_MAX__WAIT__MILLIS));
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<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>
|
||||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-db-vendor-mysql</artifactId>
|
||||
<name>Che Core :: Commons :: DB :: Vendor MySQL</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>jakarta.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.mysql.jpa.eclipselink;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
|
||||
import org.eclipse.che.core.db.jpa.IntegrityConstraintViolationException;
|
||||
import org.eclipse.persistence.exceptions.DatabaseException;
|
||||
import org.eclipse.persistence.exceptions.ExceptionHandler;
|
||||
|
||||
/**
|
||||
* Rethrows vendor specific exceptions as common exceptions. See <a
|
||||
* href="https://dev.mysql.com/doc/refman/8.0/en/error-messages-server.html">MySQL error codes</a>.
|
||||
*
|
||||
* @author Barry Dresdner
|
||||
*/
|
||||
public class MySqlExceptionHandler implements ExceptionHandler {
|
||||
@Override
|
||||
public Object handleException(RuntimeException exception) {
|
||||
if (exception instanceof DatabaseException && exception.getCause() instanceof SQLException) {
|
||||
final SQLException sqlEx = (SQLException) exception.getCause();
|
||||
switch (sqlEx.getErrorCode()) {
|
||||
case 1062:
|
||||
throw new DuplicateKeyException(exception.getMessage(), exception);
|
||||
case 1452:
|
||||
throw new IntegrityConstraintViolationException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<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>
|
||||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-db-vendor-postgresql</artifactId>
|
||||
<name>Che Core :: Commons :: DB :: Vendor PostgreSQL</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-db</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>jakarta.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.postgresql;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
|
||||
import org.eclipse.che.core.db.JNDIDataSourceFactory;
|
||||
|
||||
/**
|
||||
* Environment params based JNDI data source factory for Postgres.
|
||||
*
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
public class PostgreSQLJndiDataSourceFactory extends JNDIDataSourceFactory {
|
||||
|
||||
private static final String DEFAULT_USERNAME = "pgche";
|
||||
private static final String DEFAULT_PASSWORD = "pgchepassword";
|
||||
private static final String DEFAULT_URL = "jdbc:postgresql://postgres:5432/dbche";
|
||||
private static final String DEFAULT_DRIVER__CLASS__NAME = "org.postgresql.Driver";
|
||||
private static final String DEFAULT_MAX__TOTAL = "20";
|
||||
private static final String DEFAULT_MAX__IDLE = "2";
|
||||
private static final String DEFAULT_MAX__WAIT__MILLIS = "-1";
|
||||
|
||||
public PostgreSQLJndiDataSourceFactory() throws Exception {
|
||||
super(
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_USERNAME")), DEFAULT_USERNAME),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_PASSWORD")), DEFAULT_PASSWORD),
|
||||
firstNonNull(nullStringToNullReference(System.getenv("CHE_JDBC_URL")), DEFAULT_URL),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_DRIVER__CLASS__NAME")),
|
||||
DEFAULT_DRIVER__CLASS__NAME),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__TOTAL")), DEFAULT_MAX__TOTAL),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__IDLE")), DEFAULT_MAX__IDLE),
|
||||
firstNonNull(
|
||||
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__WAIT__MILLIS")),
|
||||
DEFAULT_MAX__WAIT__MILLIS));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.postgresql.jpa.eclipselink;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
|
||||
import org.eclipse.che.core.db.jpa.IntegrityConstraintViolationException;
|
||||
import org.eclipse.persistence.exceptions.DatabaseException;
|
||||
import org.eclipse.persistence.exceptions.ExceptionHandler;
|
||||
|
||||
/**
|
||||
* Rethrows vendor specific exceptions as common exceptions. See <a
|
||||
* href="https://www.postgresql.org/docs/9.4/static/errcodes-appendix.html">PostgreSQL error
|
||||
* codes</a>.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
public class PostgreSqlExceptionHandler implements ExceptionHandler {
|
||||
public Object handleException(RuntimeException exception) {
|
||||
if (exception instanceof DatabaseException && exception.getCause() instanceof SQLException) {
|
||||
final SQLException sqlEx = (SQLException) exception.getCause();
|
||||
switch (sqlEx.getSQLState()) {
|
||||
case "23505":
|
||||
throw new DuplicateKeyException(exception.getMessage(), exception);
|
||||
case "23503":
|
||||
throw new IntegrityConstraintViolationException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<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>
|
||||
<parent>
|
||||
<artifactId>che-core-parent</artifactId>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<version>7.73.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>che-core-db</artifactId>
|
||||
<name>Che Core :: Commons :: DB</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentracing</groupId>
|
||||
<artifactId>opentracing-util</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentracing.contrib</groupId>
|
||||
<artifactId>opentracing-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.inject</groupId>
|
||||
<artifactId>jakarta.inject-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-dbcp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-inject</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.extension</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>jakarta.persistence</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-lang</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db;
|
||||
|
||||
/**
|
||||
* Defines common database error codes which should be used throughout the application in preference
|
||||
* to vendor specific error codes.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public enum DBErrorCode {
|
||||
|
||||
/** When database error can't be described with one of the other values of this enumeration. */
|
||||
UNDEFINED(-1),
|
||||
|
||||
/**
|
||||
* When any of the unique constraints is violated e.g. duplicate key or unique index violation.
|
||||
*/
|
||||
DUPLICATE_KEY(1),
|
||||
|
||||
/** When entity referenced foreign key does not exist */
|
||||
INTEGRITY_CONSTRAINT_VIOLATION(2);
|
||||
|
||||
private final int code;
|
||||
|
||||
DBErrorCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/** Returns the code of this error. */
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import org.eclipse.che.core.db.jpa.JpaInitializer;
|
||||
import org.eclipse.che.core.db.jpa.eclipselink.GuiceEntityListenerInjectionManager;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializationException;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializer;
|
||||
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||
|
||||
/**
|
||||
* Initializes database components.
|
||||
*
|
||||
* <p>Those components which require any persistence operations on their bootstrap have to depend on
|
||||
* this component. For example:
|
||||
*
|
||||
* <pre>
|
||||
* class StackExistsChecker {
|
||||
*
|
||||
* @@Inject
|
||||
* @SuppressWarnings("unused")
|
||||
* private DBInitializer dbInitializer;
|
||||
*
|
||||
* @PostConstruct
|
||||
* public void check() {
|
||||
* ....
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* In this way it is guaranteed that all database related components will be appropriately
|
||||
* initialized before {@code check} method is executed.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@Singleton
|
||||
public class DBInitializer {
|
||||
|
||||
/**
|
||||
* when value for this key true, then its mean that db is initialized at first time, otherwise db
|
||||
* was previously initialized
|
||||
*/
|
||||
public static final String BARE_DB_INIT_PROPERTY_NAME = "bare_database_init";
|
||||
|
||||
private final Map<String, String> initProperties;
|
||||
|
||||
@Inject
|
||||
public DBInitializer(SchemaInitializer schemaInitializer, JpaInitializer jpaInitializer)
|
||||
throws SchemaInitializationException {
|
||||
// schema must be initialized before any other component that may interact with database
|
||||
initProperties = ImmutableMap.copyOf(schemaInitializer.init());
|
||||
|
||||
// jpa initialization goes next
|
||||
jpaInitializer.init();
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setUpInjectionManager(
|
||||
GuiceEntityListenerInjectionManager injManager, EntityManagerFactory emFactory) {
|
||||
final AbstractSession session = emFactory.unwrap(AbstractSession.class);
|
||||
session.setInjectionManager(injManager);
|
||||
}
|
||||
|
||||
/** Returns map of properties which represents state of database while initialization process */
|
||||
public Map<String, String> getInitProperties() {
|
||||
return initProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true only if database was initialized at first time otherwise false would be returned
|
||||
*/
|
||||
public boolean isBareInit() {
|
||||
return Boolean.parseBoolean(initProperties.get(BARE_DB_INIT_PROPERTY_NAME));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.PersistService;
|
||||
import java.lang.reflect.Field;
|
||||
import javax.inject.Singleton;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||
import org.eclipse.persistence.internal.sessions.coordination.jgroups.JGroupsRemoteConnection;
|
||||
import org.eclipse.persistence.sessions.coordination.CommandManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Stops {@link PersistService} when a system is ready to shutdown.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
@Singleton
|
||||
public class DBTermination {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DBTermination.class);
|
||||
|
||||
private final PersistService persistService;
|
||||
private final EntityManagerFactory emFactory;
|
||||
|
||||
@Inject
|
||||
public DBTermination(PersistService persistService, EntityManagerFactory emFactory) {
|
||||
this.persistService = persistService;
|
||||
this.emFactory = emFactory;
|
||||
}
|
||||
|
||||
/** Stops {@link PersistService}. Any DB operations are impossible after that. */
|
||||
public void terminate() {
|
||||
try {
|
||||
LOG.info("Stopping persistence service.");
|
||||
fixJChannelClosing(emFactory);
|
||||
persistService.stop();
|
||||
} catch (RuntimeException ex) {
|
||||
LOG.error("Failed to stop persistent service. Cause: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is hack that changes value of {@link JGroupsRemoteConnection#isLocal} to false.
|
||||
* This is needed to close the JGroups EclipseLinkCommandChannel and as result gracefully stop of
|
||||
* the system.<br>
|
||||
* For more details see {@link JGroupsRemoteConnection#closeInternal()}
|
||||
*
|
||||
* <p>The corresponding eclipse-link extension issue
|
||||
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=534148
|
||||
*/
|
||||
private void fixJChannelClosing(EntityManagerFactory emFactory) {
|
||||
try {
|
||||
final AbstractSession session = emFactory.unwrap(AbstractSession.class);
|
||||
CommandManager commandManager = session.getCommandManager();
|
||||
if (commandManager == null) {
|
||||
// not cluster mode
|
||||
return;
|
||||
}
|
||||
final JGroupsRemoteConnection conn =
|
||||
(JGroupsRemoteConnection) commandManager.getTransportManager().getConnectionToLocalHost();
|
||||
final Field isLocal = conn.getClass().getDeclaredField("isLocal");
|
||||
isLocal.setAccessible(true);
|
||||
isLocal.set(conn, false);
|
||||
} catch (IllegalAccessException | NoSuchFieldException ex) {
|
||||
LOG.error(
|
||||
"Failed to change JGroupsRemoteConnection#isLocal. This may prevent the graceful stop of "
|
||||
+ "the system because EclipseLinkCommandChannel will not be closed. Cause: "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db;
|
||||
|
||||
import static org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory.createDataSource;
|
||||
import static org.eclipse.che.core.db.TracingDataSource.wrapWithTracingIfEnabled;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.spi.ObjectFactory;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Abstract JNDI factory that constructs {@link BasicDataSource} objects from the given params.
|
||||
* Should not be used directly and must be subclassed to provide instantiation params from needful
|
||||
* source.
|
||||
*
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
public abstract class JNDIDataSourceFactory implements ObjectFactory {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JNDIDataSourceFactory.class);
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public JNDIDataSourceFactory(
|
||||
String userName,
|
||||
String password,
|
||||
String url,
|
||||
String driverClassName,
|
||||
String maxTotal,
|
||||
String maxIdle,
|
||||
String maxWaitMillis)
|
||||
throws Exception {
|
||||
Properties poolConfigurationProperties = new Properties();
|
||||
poolConfigurationProperties.setProperty("username", userName);
|
||||
poolConfigurationProperties.setProperty("password", password);
|
||||
poolConfigurationProperties.setProperty("url", url);
|
||||
poolConfigurationProperties.setProperty("driverClassName", driverClassName);
|
||||
poolConfigurationProperties.setProperty("maxTotal", maxTotal);
|
||||
poolConfigurationProperties.setProperty("maxIdle", maxIdle);
|
||||
poolConfigurationProperties.setProperty("maxWaitMillis", maxWaitMillis);
|
||||
dataSource = wrapWithTracingIfEnabled(createDataSource(poolConfigurationProperties));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObjectInstance(
|
||||
Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
|
||||
LOG.info(
|
||||
"This={} obj={} name={} Context={} environment={}", this, obj, name, nameCtx, environment);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Util method to convert string {@code "NULL"} to null reference. Allows to set string {@code
|
||||
* "NULL"} as a value of the property instead of making sure it is unset as it is done in {@link
|
||||
* org.eclipse.che.inject.CheBootstrap}
|
||||
*
|
||||
* @param value value to transform if needed
|
||||
* @return null or passed value
|
||||
*/
|
||||
protected static String nullStringToNullReference(String value) {
|
||||
return "NULL".equals(value) ? null : value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* Provides data source based on jndi resource name.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class JndiDataSourceProvider implements Provider<DataSource> {
|
||||
|
||||
@Inject
|
||||
@Named("jndi.datasource.name")
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public DataSource get() {
|
||||
try {
|
||||
final InitialContext context = new InitialContext();
|
||||
return (DataSource) context.lookup(name);
|
||||
} catch (NamingException x) {
|
||||
throw new IllegalStateException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import io.opentracing.contrib.jdbc.ConnectionInfo;
|
||||
import io.opentracing.contrib.jdbc.TracingConnection;
|
||||
import io.opentracing.contrib.jdbc.parser.URLParser;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.logging.Logger;
|
||||
import javax.sql.DataSource;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Adding tracing support for existing @{@link javax.sql.DataSource}. DbType and DbUser information
|
||||
* omitted in traces. Traced are made only if active span exists. Prerequisites of using this class
|
||||
* is that @{@link io.opentracing.Tracer} should be set in @{@link io.opentracing.util.GlobalTracer}
|
||||
*
|
||||
* @author Sergii Kabashniuk
|
||||
*/
|
||||
@Beta
|
||||
public class TracingDataSource implements DataSource {
|
||||
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(TracingDataSource.class);
|
||||
|
||||
private final DataSource delegate;
|
||||
private final ConnectionInfo connectionInfo;
|
||||
|
||||
public TracingDataSource(DataSource delegate) {
|
||||
this.delegate = delegate;
|
||||
try (Connection connection = delegate.getConnection()) {
|
||||
connectionInfo = URLParser.parser(connection.getMetaData().getURL());
|
||||
LOG.debug(
|
||||
"URL {} connectionInfo {}",
|
||||
connection.getMetaData().getURL(),
|
||||
connectionInfo.getPeerService());
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return new TracingConnection(
|
||||
delegate.getConnection(), connectionInfo, true, null, GlobalTracer.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
return new TracingConnection(
|
||||
delegate.getConnection(username, password), connectionInfo, true, null, GlobalTracer.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return delegate.unwrap(iface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return delegate.isWrapperFor(iface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return delegate.getLogWriter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
||||
delegate.setLogWriter(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoginTimeout(int seconds) throws SQLException {
|
||||
delegate.setLoginTimeout(seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoginTimeout() throws SQLException {
|
||||
return delegate.getLoginTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return delegate.getParentLogger();
|
||||
}
|
||||
|
||||
public static DataSource wrapWithTracingIfEnabled(DataSource dataSource) {
|
||||
return Boolean.valueOf(System.getenv("CHE_DB_TRACING_ENABLED"))
|
||||
? new TracingDataSource(dataSource)
|
||||
: dataSource;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.cascade;
|
||||
|
||||
/**
|
||||
* Context that is used only for sharing the state of the cascading operation among subscribers.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
* @author Sergii Leshchenko
|
||||
*/
|
||||
public class CascadeContext {
|
||||
private Exception cause;
|
||||
|
||||
/** Returns the cause which has changed the state of the context. */
|
||||
public Exception getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
/** Returns the state of the context. */
|
||||
public boolean isFailed() {
|
||||
return cause != null;
|
||||
}
|
||||
|
||||
/** Sets the context into failed state. */
|
||||
public CascadeContext fail(Exception cause) {
|
||||
this.cause = cause;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.cascade;
|
||||
|
||||
import org.eclipse.che.api.core.notification.EventSubscriber;
|
||||
import org.eclipse.che.core.db.cascade.event.CascadeEvent;
|
||||
|
||||
/**
|
||||
* Receives events and puts exceptions in the context to perform rollback operation if it is
|
||||
* necessary.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public abstract class CascadeEventSubscriber<T extends CascadeEvent> implements EventSubscriber<T> {
|
||||
@Override
|
||||
public void onEvent(T event) {
|
||||
if (!event.getContext().isFailed()) {
|
||||
try {
|
||||
onCascadeEvent(event);
|
||||
} catch (Exception ex) {
|
||||
event.getContext().fail(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives notification about cascade event.
|
||||
*
|
||||
* <p>If the method throws an exception it will be set to context to break event publishing and
|
||||
* rethrow exception. Event is responsible for rethrowing or wrapping original exception.
|
||||
*
|
||||
* @see CascadeEvent#propagateException()
|
||||
*/
|
||||
public abstract void onCascadeEvent(T event) throws Exception;
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.cascade.event;
|
||||
|
||||
import org.eclipse.che.core.db.cascade.CascadeContext;
|
||||
|
||||
/**
|
||||
* Special event type which is needed only for notification in the process which can require cascade
|
||||
* operation.
|
||||
*
|
||||
* <p>Publisher should invoke {@link #propagateException()} to get cause of event canceling.
|
||||
*
|
||||
* <p>Rollback of operation must be performed when subscriber throws {@link Exception} during event
|
||||
* processing.
|
||||
*
|
||||
* <p>Usage example:
|
||||
*
|
||||
* <pre>
|
||||
* EventService bus = new EventService();
|
||||
* bus.subscribe(new CascadeEventSubscriber<MyEvent>() {
|
||||
* @Override
|
||||
* public void onCascadeEvent(MyEvent event) throws Exception {
|
||||
* if (event.getEntityName().startsWith("reserved")) {
|
||||
* throw new ConflictException("Entity name can't start with `reserved`.");
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* bus.publish(new MyEvent(...)).propagateException();
|
||||
* </pre>
|
||||
*
|
||||
* @author Anton Korneta
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public abstract class CascadeEvent {
|
||||
protected final CascadeContext context = new CascadeContext();
|
||||
|
||||
public CascadeContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagates exception if subscriber throws it while event processing otherwise do nothing
|
||||
*
|
||||
* @throws Exception when any subscriber throws {@link Exception}
|
||||
*/
|
||||
public void propagateException() throws Exception {
|
||||
if (context.isFailed()) {
|
||||
throw context.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.cascade.event;
|
||||
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
/**
|
||||
* Cascade event about an entity persisting.
|
||||
*
|
||||
* <p>{@link ConflictException} or {@link ServerException} can be rethrown during exception
|
||||
* propagating.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public abstract class PersistEvent extends CascadeEvent {
|
||||
@Override
|
||||
public void propagateException() throws ConflictException, ServerException {
|
||||
if (context.isFailed()) {
|
||||
try {
|
||||
throw context.getCause();
|
||||
} catch (ConflictException | ServerException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.cascade.event;
|
||||
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
/**
|
||||
* Cascade event about an entity removing.
|
||||
*
|
||||
* <p>{@link ServerException} can be rethrown during exception propagating.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public abstract class RemoveEvent extends CascadeEvent {
|
||||
@Override
|
||||
public void propagateException() throws ServerException {
|
||||
if (context.isFailed()) {
|
||||
try {
|
||||
throw context.getCause();
|
||||
} catch (ServerException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.cascade.event;
|
||||
|
||||
import org.eclipse.che.api.core.ConflictException;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
||||
/**
|
||||
* Cascade event about an entity updating.
|
||||
*
|
||||
* <p>{@link NotFoundException}, {@link ConflictException} or {@link ServerException} can be
|
||||
* rethrown during exception propagating.
|
||||
*
|
||||
* @author Sergii Leschenko
|
||||
*/
|
||||
public abstract class UpdateEvent extends CascadeEvent {
|
||||
@Override
|
||||
public void propagateException() throws NotFoundException, ConflictException, ServerException {
|
||||
if (context.isFailed()) {
|
||||
try {
|
||||
throw context.getCause();
|
||||
} catch (NotFoundException | ConflictException | ServerException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new ServerException(e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.jpa;
|
||||
|
||||
import javax.persistence.RollbackException;
|
||||
import org.eclipse.che.core.db.DBErrorCode;
|
||||
|
||||
/**
|
||||
* Extends the standard {@link RollbackException} with an error code from {@link DBErrorCode}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class DetailedRollbackException extends RollbackException {
|
||||
|
||||
private DBErrorCode code;
|
||||
|
||||
public DetailedRollbackException(String message, Throwable cause, DBErrorCode code) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public DBErrorCode getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.jpa;
|
||||
|
||||
import org.eclipse.che.core.db.DBErrorCode;
|
||||
|
||||
/**
|
||||
* Thrown when data couldn't be updated/stored due to unique constrain violation.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @see DBErrorCode#DUPLICATE_KEY
|
||||
*/
|
||||
public class DuplicateKeyException extends DetailedRollbackException {
|
||||
|
||||
public DuplicateKeyException(String message, Throwable cause) {
|
||||
super(message, cause, DBErrorCode.DUPLICATE_KEY);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.jpa;
|
||||
|
||||
import org.eclipse.che.core.db.DBErrorCode;
|
||||
|
||||
/**
|
||||
* Throws during inserts/updates entity that restricted by referential integrity and given
|
||||
* insert/update refers to non-existing entity.
|
||||
*
|
||||
* @author Anton Korneta
|
||||
* @see DBErrorCode#INTEGRITY_CONSTRAINT_VIOLATION
|
||||
*/
|
||||
public class IntegrityConstraintViolationException extends DetailedRollbackException {
|
||||
|
||||
public IntegrityConstraintViolationException(String message, Throwable cause) {
|
||||
super(message, cause, DBErrorCode.INTEGRITY_CONSTRAINT_VIOLATION);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.jpa;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
import org.eclipse.che.core.db.jpa.guice.GuiceJpaInitializer;
|
||||
|
||||
/**
|
||||
* Initializes jpa components.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
@ImplementedBy(GuiceJpaInitializer.class)
|
||||
public interface JpaInitializer {
|
||||
|
||||
/** Initialized jpa components. */
|
||||
void init();
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.jpa.eclipselink;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import javax.naming.NamingException;
|
||||
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||
import org.eclipse.persistence.internal.sessions.cdi.InjectionManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Allows to use dependency injection in entity listeners.
|
||||
*
|
||||
* <p>Example:
|
||||
*
|
||||
* <pre>
|
||||
* class WorkspaceEntityListener {
|
||||
*
|
||||
* @Inject EventBus bus; <- EventBus will be injected by Guice
|
||||
*
|
||||
* @PreRemove
|
||||
* public void preRemove(Workspace workspace) {
|
||||
* bus.post(new BeforeWorkspaceRemovedEvent(workspace));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Entity
|
||||
* @EntityListeners(WorkspaceEntityListener.class)
|
||||
* class Workspace {
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class GuiceEntityListenerInjectionManager implements InjectionManager {
|
||||
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(GuiceEntityListenerInjectionManager.class);
|
||||
|
||||
@Inject private Injector injector;
|
||||
|
||||
@Override
|
||||
public Object createManagedBeanAndInjectDependencies(Class entityListenerClass)
|
||||
throws NamingException {
|
||||
try {
|
||||
return injector.getInstance(entityListenerClass);
|
||||
} catch (RuntimeException x) {
|
||||
LOG.error(x.getLocalizedMessage(), x);
|
||||
throw new NamingException(x.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp(AbstractSession session) {
|
||||
// EntityListener objects are managed by Guice, nothing to cleanup
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.jpa.guice;
|
||||
|
||||
import com.google.inject.persist.PersistService;
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.core.db.jpa.JpaInitializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Should be bound as eager singleton. See <a
|
||||
* href="https://github.com/google/guice/wiki/JPA">doc</a>
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
* @author Anton Korneta
|
||||
*/
|
||||
public class GuiceJpaInitializer implements JpaInitializer {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GuiceJpaInitializer.class);
|
||||
|
||||
@Inject private PersistService persistService;
|
||||
|
||||
public void init() {
|
||||
try {
|
||||
persistService.start();
|
||||
} catch (Exception x) {
|
||||
LOG.error(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema;
|
||||
|
||||
/**
|
||||
* Thrown when any schema initialization/migration problem occurs.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class SchemaInitializationException extends Exception {
|
||||
|
||||
public SchemaInitializationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public SchemaInitializationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Initializes database schema or migrates an old version of it to a new one.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public interface SchemaInitializer {
|
||||
|
||||
/**
|
||||
* Initializes database schema or migrates an old schema to a new one.
|
||||
*
|
||||
* @return initialization properties
|
||||
* @throws SchemaInitializationException thrown when any error occurs during schema
|
||||
* initialization/migration
|
||||
*/
|
||||
Map<String, String> init() throws SchemaInitializationException;
|
||||
}
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteSource;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.flywaydb.core.api.FlywayException;
|
||||
import org.flywaydb.core.api.MigrationType;
|
||||
import org.flywaydb.core.api.MigrationVersion;
|
||||
import org.flywaydb.core.api.resolver.BaseMigrationResolver;
|
||||
import org.flywaydb.core.api.resolver.ResolvedMigration;
|
||||
import org.flywaydb.core.internal.dbsupport.DbSupport;
|
||||
import org.flywaydb.core.internal.resolver.ResolvedMigrationImpl;
|
||||
import org.flywaydb.core.internal.resolver.sql.SqlMigrationExecutor;
|
||||
import org.flywaydb.core.internal.util.Location;
|
||||
import org.flywaydb.core.internal.util.PlaceholderReplacer;
|
||||
import org.flywaydb.core.internal.util.scanner.Resource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Resolves SQL migrations from the configured locations, allows overriding of default scripts with
|
||||
* vendor specific ones.
|
||||
*
|
||||
* <ul>
|
||||
* Migration scripts must follow the next rules:
|
||||
* <li>It must be placed in the project dir directory e.g. <i>5.0.1</i>
|
||||
* <li>Project dir directory must be placed in dedicated directory e.g. <i>resources/sql</i>
|
||||
* <li>Migration/Initialization script name must start with a number e.g <i>1.init.sql</i>, this
|
||||
* number indicates the subversion of the database migration, e.g. for dir <i>5.0.0</i> and
|
||||
* migration script <i>1.init.sql</i> database migration dir will be <i>5.0.0.1</i>
|
||||
* <li>If a file is not a part of migration it shouldn't end with migration prefix e.g.
|
||||
* <i>.sql</i> then resolver will ignore it
|
||||
* </ul>
|
||||
*
|
||||
* <p>For the structure:
|
||||
*
|
||||
* <pre>
|
||||
* resources/
|
||||
* sql/
|
||||
* 5.0.0/
|
||||
* 1.init.sql
|
||||
* 5.0.0-M1/
|
||||
* 1.rename_fields.sql
|
||||
* 2.add_workspace_constraint.sql
|
||||
* postgresql/
|
||||
* 2.add_workspace_constraint.sql
|
||||
* 5.0.1/
|
||||
* 1.stacks_migration.sql
|
||||
* </pre>
|
||||
*
|
||||
* And configuration:
|
||||
*
|
||||
* <pre>
|
||||
* prefix - ""
|
||||
* suffix - ".sql"
|
||||
* separator - "."
|
||||
* locations - "classpath:sql"
|
||||
* </pre>
|
||||
*
|
||||
* <ul>
|
||||
* 4 database migrations will be resolved
|
||||
* <li>5.0.0.1 - initialization script based on file <i>sql/5.0.0/1.init.sql</i>
|
||||
* <li>5.0.0.1.1 - modification script based on file <i>sql/5.0.0-M1/1.rename_fields.sql</i>
|
||||
* <li>5.0.0.1.2 - modification script(if postgresql is current provider) based on file
|
||||
* <i>sql/5.0.0-M1/postgresql/2.add_workspace_constraint.sql</i>
|
||||
* <li>5.0.1.1 - modification script based on file <i>sql/5.0.1/1.stacks_migrations.sql</i>
|
||||
* </ul>
|
||||
*
|
||||
* <p>It is also possible to configure several locations then all of those locations will be
|
||||
* analyzed for migration scripts existence. For example:
|
||||
*
|
||||
* <p>For the structure:
|
||||
*
|
||||
* <pre>
|
||||
* che/
|
||||
* resources/
|
||||
* che-schema/
|
||||
* 5.0.0/
|
||||
* 1.init.sql
|
||||
* another-project/
|
||||
* resources/
|
||||
* custom-schema/
|
||||
* 5.0.0/
|
||||
* 2.init_additional_tables.sql
|
||||
* </pre>
|
||||
*
|
||||
* And configuration:
|
||||
*
|
||||
* <pre>
|
||||
* prefix - ""
|
||||
* suffix - ".sql"
|
||||
* separator - "."
|
||||
* locations - "classpath:che-schema, classpath:custom-schema"
|
||||
* </pre>
|
||||
*
|
||||
* <ul>
|
||||
* 2 database migrations will be resolved
|
||||
* <li>5.0.0.1 - initialization script based on file <i>che-schema/5.0.0/1.init.sql</i>
|
||||
* <li>5.0.0.2 - modification script based on file
|
||||
* <i>custom-schema/5.0.0/2.init_additional_tables.sql</i>
|
||||
* </ul>
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class CustomSqlMigrationResolver extends BaseMigrationResolver {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CustomSqlMigrationResolver.class);
|
||||
|
||||
private final String vendorName;
|
||||
private final ResourcesFinder finder;
|
||||
private final VersionResolver versionResolver;
|
||||
private final SqlScriptCreator scriptsCreator;
|
||||
private final DbSupport dbSupport;
|
||||
private final PlaceholderReplacer placeholderReplacer;
|
||||
|
||||
public CustomSqlMigrationResolver(
|
||||
String dbProviderName, DbSupport dbSupport, PlaceholderReplacer placeholderReplacer) {
|
||||
this.vendorName = dbProviderName;
|
||||
this.dbSupport = dbSupport;
|
||||
this.placeholderReplacer = placeholderReplacer;
|
||||
this.finder = new ResourcesFinder();
|
||||
this.versionResolver = new VersionResolver();
|
||||
this.scriptsCreator = new SqlScriptCreator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResolvedMigration> resolveMigrations() {
|
||||
try {
|
||||
return resolveSqlMigrations();
|
||||
} catch (IOException | SQLException x) {
|
||||
throw new RuntimeException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ResolvedMigration> resolveSqlMigrations() throws IOException, SQLException {
|
||||
LOG.info(
|
||||
"Searching for SQL scripts in locations {}",
|
||||
Arrays.toString(flywayConfiguration.getLocations()));
|
||||
final Map<Location, List<Resource>> allResources = finder.findResources(flywayConfiguration);
|
||||
LOG.debug("Found scripts: {}", allResources);
|
||||
|
||||
final Map<String, Map<String, SqlScript>> scriptsInDir = new HashMap<>();
|
||||
for (Location location : allResources.keySet()) {
|
||||
final List<Resource> resources = allResources.get(location);
|
||||
for (Resource resource : resources) {
|
||||
final SqlScript newScript = scriptsCreator.createScript(location, resource);
|
||||
if (!scriptsInDir.containsKey(newScript.dir)) {
|
||||
scriptsInDir.put(newScript.dir, new HashMap<>(4));
|
||||
}
|
||||
final Map<String, SqlScript> existingScripts = scriptsInDir.get(newScript.dir);
|
||||
final SqlScript existingScript = existingScripts.get(newScript.name);
|
||||
if (existingScript == null) {
|
||||
existingScripts.put(newScript.name, newScript);
|
||||
} else if (Objects.equals(existingScript.vendor, newScript.vendor)) {
|
||||
throw new FlywayException(
|
||||
format(
|
||||
"More than one script with name '%s' is registered for "
|
||||
+ "database vendor '%s', script '%s' conflicts with '%s'",
|
||||
newScript.name, existingScript.vendor, newScript, existingScript));
|
||||
} else if (vendorName.equals(newScript.vendor)) {
|
||||
existingScripts.put(newScript.name, newScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Map<MigrationVersion, ResolvedMigration> migrations = new HashMap<>();
|
||||
for (SqlScript script :
|
||||
scriptsInDir.values().stream()
|
||||
.flatMap(scripts -> scripts.values().stream())
|
||||
.collect(toList())) {
|
||||
final ResolvedMigrationImpl migration = new ResolvedMigrationImpl();
|
||||
migration.setVersion(versionResolver.resolve(script, flywayConfiguration));
|
||||
migration.setScript(script.resource.getLocation());
|
||||
migration.setPhysicalLocation(script.resource.getLocationOnDisk());
|
||||
migration.setType(MigrationType.SQL);
|
||||
migration.setDescription(script.name);
|
||||
migration.setChecksum(
|
||||
ByteSource.wrap(script.resource.loadAsBytes()).hash(Hashing.crc32()).asInt());
|
||||
migration.setExecutor(
|
||||
new SqlMigrationExecutor(
|
||||
dbSupport, script.resource, placeholderReplacer, flywayConfiguration));
|
||||
if (migrations.put(migration.getVersion(), migration) != null) {
|
||||
throw new FlywayException("Two migrations with the same version detected");
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(migrations.values());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static org.eclipse.che.core.db.DBInitializer.BARE_DB_INIT_PROPERTY_NAME;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.sql.DataSource;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializationException;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializer;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.flywaydb.core.internal.dbsupport.DbSupport;
|
||||
import org.flywaydb.core.internal.dbsupport.DbSupportFactory;
|
||||
import org.flywaydb.core.internal.metadatatable.MetaDataTable;
|
||||
import org.flywaydb.core.internal.metadatatable.MetaDataTableImpl;
|
||||
import org.flywaydb.core.internal.util.PlaceholderReplacer;
|
||||
|
||||
/**
|
||||
* <a href="https://flywaydb.org/">Flyway</a> based schema initializer.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class FlywaySchemaInitializer implements SchemaInitializer {
|
||||
|
||||
private final DataSource dataSource;
|
||||
private final String[] locations;
|
||||
private final String scriptsPrefix;
|
||||
private final String scriptsSuffix;
|
||||
private final String versionSeparator;
|
||||
private final boolean baselineOnMigrate;
|
||||
private final String baselineVersion;
|
||||
private final PlaceholderReplacer placeholderReplacer;
|
||||
|
||||
/**
|
||||
* Creates a new instance of flyway schema initializer.
|
||||
*
|
||||
* @param scriptsLocations the locations where to search migration scripts, if locations is not
|
||||
* prefixed or prefixed with <i>classpath:</i> then initializer will try to find scripts in
|
||||
* classpath using {@code Thread.currentThread().}{@link Thread#getContextClassLoader()
|
||||
* getContextClassLoader()}
|
||||
* @param scriptsPrefix prefix of migration scripts e.g. 'v' or empty string
|
||||
* @param scriptsSuffix suffix of migration scripts e.g. '.sql'
|
||||
* @param versionSeparator separate version from the other part of script name e.g. '.' or '__'
|
||||
* @param baselineOnMigrate whether to ignore scripts up to the version configured by {@code
|
||||
* baselineVersion}
|
||||
* @param baselineVersion up to this version all the scripts ignored, unless schema is initialized
|
||||
* first time, note that scripts with version equal to baseline version are also ignored
|
||||
* @param dataSource data source used for migrations
|
||||
* @param placeholderReplacer used to replace variables in script with configured values
|
||||
*/
|
||||
@Inject
|
||||
public FlywaySchemaInitializer(
|
||||
@Named("db.schema.flyway.scripts.locations") String[] scriptsLocations,
|
||||
@Named("db.schema.flyway.scripts.prefix") String scriptsPrefix,
|
||||
@Named("db.schema.flyway.scripts.suffix") String scriptsSuffix,
|
||||
@Named("db.schema.flyway.scripts.version_separator") String versionSeparator,
|
||||
@Named("db.schema.flyway.baseline.enabled") boolean baselineOnMigrate,
|
||||
@Named("db.schema.flyway.baseline.version") String baselineVersion,
|
||||
DataSource dataSource,
|
||||
PlaceholderReplacer placeholderReplacer) {
|
||||
this.dataSource = dataSource;
|
||||
this.locations = scriptsLocations;
|
||||
this.scriptsPrefix = scriptsPrefix;
|
||||
this.scriptsSuffix = scriptsSuffix;
|
||||
this.versionSeparator = versionSeparator;
|
||||
this.baselineOnMigrate = baselineOnMigrate;
|
||||
this.baselineVersion = baselineVersion;
|
||||
this.placeholderReplacer = placeholderReplacer;
|
||||
}
|
||||
|
||||
/** Creates a new flyway based initializer with default values. */
|
||||
public FlywaySchemaInitializer(DataSource dataSource, String... locations) {
|
||||
this(locations, "", ".sql", "__", false, "", dataSource, PlaceholderReplacer.NO_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> init() throws SchemaInitializationException {
|
||||
final Map<String, String> initResult = new HashMap<>();
|
||||
try (final Connection conn = dataSource.getConnection()) {
|
||||
final Flyway flyway = new Flyway();
|
||||
flyway.setDataSource(dataSource);
|
||||
flyway.setLocations(locations);
|
||||
flyway.setClassLoader(Thread.currentThread().getContextClassLoader());
|
||||
final DbSupport dbSupport = DbSupportFactory.createDbSupport(conn, true);
|
||||
final MetaDataTable mt =
|
||||
new MetaDataTableImpl(
|
||||
dbSupport,
|
||||
dbSupport.getOriginalSchema().getTable(flyway.getTable()),
|
||||
flyway.getInstalledBy());
|
||||
initResult.put(BARE_DB_INIT_PROPERTY_NAME, String.valueOf(!mt.hasAppliedMigrations()));
|
||||
final String productName = conn.getMetaData().getDatabaseProductName().toLowerCase();
|
||||
flyway.setResolvers(
|
||||
new CustomSqlMigrationResolver(productName, dbSupport, placeholderReplacer));
|
||||
flyway.setSkipDefaultResolvers(true);
|
||||
flyway.setBaselineOnMigrate(baselineOnMigrate);
|
||||
if (baselineOnMigrate) {
|
||||
flyway.setBaselineVersionAsString(baselineVersion);
|
||||
}
|
||||
flyway.setSqlMigrationSeparator(versionSeparator);
|
||||
flyway.setSqlMigrationSuffix(scriptsSuffix);
|
||||
flyway.setSqlMigrationPrefix(scriptsPrefix);
|
||||
flyway.migrate();
|
||||
} catch (SQLException | RuntimeException x) {
|
||||
throw new SchemaInitializationException(x.getLocalizedMessage(), x);
|
||||
}
|
||||
return initResult;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import org.eclipse.che.inject.ConfigurationProperties;
|
||||
import org.flywaydb.core.internal.util.PlaceholderReplacer;
|
||||
|
||||
/**
|
||||
* Placeholder replacer that uses configuration properties.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class PlaceholderReplacerProvider implements Provider<PlaceholderReplacer> {
|
||||
|
||||
private final PlaceholderReplacer replacer;
|
||||
|
||||
@Inject
|
||||
public PlaceholderReplacerProvider(ConfigurationProperties properties) {
|
||||
replacer = new PlaceholderReplacer(properties.getProperties(".*"), "${", "}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaceholderReplacer get() {
|
||||
return replacer;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.flywaydb.core.api.configuration.FlywayConfiguration;
|
||||
import org.flywaydb.core.internal.util.Location;
|
||||
import org.flywaydb.core.internal.util.scanner.Resource;
|
||||
import org.flywaydb.core.internal.util.scanner.classpath.ClassPathScanner;
|
||||
import org.flywaydb.core.internal.util.scanner.filesystem.FileSystemScanner;
|
||||
|
||||
/**
|
||||
* Searches for sql scripts in given places.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
class ResourcesFinder {
|
||||
|
||||
/**
|
||||
* Finds script resources in configured {@link FlywayConfiguration#getLocations()}.
|
||||
*
|
||||
* @param configuration flyway configuration to find scripts
|
||||
* @return found scripts or an empty list if nothing found
|
||||
* @throws IOException when any io error occurs during scripts look up
|
||||
*/
|
||||
Map<Location, List<Resource>> findResources(FlywayConfiguration configuration)
|
||||
throws IOException {
|
||||
final String prefix = configuration.getSqlMigrationPrefix();
|
||||
final String suffix = configuration.getSqlMigrationSuffix();
|
||||
final ClassPathScanner cpScanner = new ClassPathScanner(configuration.getClassLoader());
|
||||
final FileSystemScanner fsScanner = new FileSystemScanner();
|
||||
final Map<Location, List<Resource>> resources = new HashMap<>();
|
||||
for (String rawLocation : configuration.getLocations()) {
|
||||
final Location location = new Location(rawLocation);
|
||||
if (location.isClassPath()) {
|
||||
resources.put(location, newArrayList(cpScanner.scanForResources(location, prefix, suffix)));
|
||||
} else {
|
||||
resources.put(location, newArrayList(fsScanner.scanForResources(location, prefix, suffix)));
|
||||
}
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.flywaydb.core.internal.util.Location;
|
||||
import org.flywaydb.core.internal.util.scanner.Resource;
|
||||
|
||||
/**
|
||||
* Data object for holding information about sql script.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
class SqlScript {
|
||||
|
||||
final Resource resource;
|
||||
final Location location;
|
||||
final String dir;
|
||||
final String vendor;
|
||||
final String name;
|
||||
|
||||
SqlScript(Resource resource, Location location, String dir, String vendor, String name) {
|
||||
this.resource = resource;
|
||||
this.location = location;
|
||||
this.name = name;
|
||||
this.vendor = vendor;
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof SqlScript)) {
|
||||
return false;
|
||||
}
|
||||
final SqlScript that = (SqlScript) obj;
|
||||
return Objects.equals(resource, that.resource)
|
||||
&& Objects.equals(location, that.location)
|
||||
&& Objects.equals(dir, that.dir)
|
||||
&& Objects.equals(vendor, that.vendor)
|
||||
&& Objects.equals(name, that.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Objects.hashCode(resource);
|
||||
hash = 31 * hash + Objects.hashCode(location);
|
||||
hash = 31 * hash + Objects.hashCode(dir);
|
||||
hash = 31 * hash + Objects.hashCode(vendor);
|
||||
hash = 31 * hash + Objects.hashCode(name);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SqlScript{"
|
||||
+ "resource="
|
||||
+ resource
|
||||
+ ", location="
|
||||
+ location
|
||||
+ ", dir='"
|
||||
+ dir
|
||||
+ '\''
|
||||
+ ", vendor='"
|
||||
+ vendor
|
||||
+ '\''
|
||||
+ ", name='"
|
||||
+ name
|
||||
+ '\''
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.io.File;
|
||||
import org.flywaydb.core.api.FlywayException;
|
||||
import org.flywaydb.core.internal.util.Location;
|
||||
import org.flywaydb.core.internal.util.scanner.Resource;
|
||||
|
||||
/**
|
||||
* Creates new {@link SqlScript} instance from given resource.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
class SqlScriptCreator {
|
||||
|
||||
/**
|
||||
* Create a new instance of script based on location and resource.
|
||||
*
|
||||
* @param location root location of the given resource
|
||||
* @param resource script resource
|
||||
* @return a new instance of sql script based on location and resource
|
||||
* @throws FlywayException when script can't be created from the resource
|
||||
*/
|
||||
SqlScript createScript(Location location, Resource resource) {
|
||||
final String separator = location.isClassPath() ? "/" : File.separator;
|
||||
// '/root-location/5.0.0-M7/v1__init.sql' -> '5.0.0-M7/v1__init.sql'
|
||||
final String relLocation = resource.getLocation().substring(location.getPath().length() + 1);
|
||||
final String[] paths = relLocation.split(separator);
|
||||
// 5.0.0-M1/v1__init.sql
|
||||
if (paths.length == 2) {
|
||||
return new SqlScript(resource, location, paths[0], null, paths[1]);
|
||||
}
|
||||
// 5.0.0-M1/postgresql/v1__init.sql
|
||||
if (paths.length == 3) {
|
||||
return new SqlScript(resource, location, paths[0], paths[1], paths[2]);
|
||||
}
|
||||
throw new FlywayException(
|
||||
format(
|
||||
"Sql script location must be either in 'location-root/version-dir' "
|
||||
+ "or in 'location-root/version-dir/provider-name', but script '%s' is not in root '%s'",
|
||||
resource.getLocation(), location.getPath()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import org.flywaydb.core.api.FlywayException;
|
||||
import org.flywaydb.core.api.MigrationVersion;
|
||||
import org.flywaydb.core.api.configuration.FlywayConfiguration;
|
||||
|
||||
/**
|
||||
* Creates versions for scripts depending on the provided data.
|
||||
*
|
||||
* <ul>
|
||||
* A few examples:
|
||||
* <li>5.0.0-M7/v1__init.sql => 5.0.0.7.1
|
||||
* <li>5.0.0-M8/v2.1__modify.sql => 5.0.0.8.2.1
|
||||
* </ul>
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
class VersionResolver {
|
||||
|
||||
private static final Pattern NOT_VERSION_CHARS_PATTERN = Pattern.compile("[^0-9.]");
|
||||
|
||||
private final Map<String, String> normalizedDirs = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates migration version based on script data.
|
||||
*
|
||||
* @param script script for which to resolve the version
|
||||
* @param configuration flyway configuration used for resolution parameters
|
||||
*/
|
||||
MigrationVersion resolve(SqlScript script, FlywayConfiguration configuration) {
|
||||
String normalizedDir = normalizedDirs.get(script.dir);
|
||||
if (normalizedDir == null) {
|
||||
// 5.0.0-M1 -> 5.0.0.M1 -> 5.0.0.1
|
||||
normalizedDir =
|
||||
NOT_VERSION_CHARS_PATTERN.matcher(script.dir.replace("-", ".")).replaceAll("");
|
||||
normalizedDirs.put(script.dir, normalizedDir);
|
||||
}
|
||||
|
||||
// separate version from the other part of the name
|
||||
final int sepIdx = script.name.indexOf(configuration.getSqlMigrationSeparator());
|
||||
if (sepIdx == -1) {
|
||||
throw new FlywayException(
|
||||
format(
|
||||
"sql script name '%s' is not valid, name must contain '%s'",
|
||||
script.name, configuration.getSqlMigrationSeparator()));
|
||||
}
|
||||
|
||||
// check whether part before separator is not empty
|
||||
String version = script.name.substring(0, sepIdx);
|
||||
if (version.isEmpty()) {
|
||||
throw new FlywayException(
|
||||
format(
|
||||
"sql script name '%s' is not valid, name must provide version like "
|
||||
+ "'%s4%smigration_description.sql",
|
||||
configuration.getSqlMigrationPrefix(),
|
||||
script.name,
|
||||
configuration.getSqlMigrationSeparator()));
|
||||
}
|
||||
|
||||
// extract sql script version without prefix
|
||||
final String prefix = configuration.getSqlMigrationPrefix();
|
||||
if (!isNullOrEmpty(prefix) && script.name.startsWith(prefix)) {
|
||||
version = version.substring(prefix.length());
|
||||
}
|
||||
return MigrationVersion.fromVersion(normalizedDir + '.' + version);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db;
|
||||
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.opentracing.contrib.jdbc.TracingConnection;
|
||||
import java.lang.reflect.Field;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners(value = {MockitoTestNGListener.class})
|
||||
public class TracingDataSourceTest {
|
||||
|
||||
@Mock DataSource dataSource;
|
||||
@Mock Connection connection;
|
||||
@Mock DatabaseMetaData databaseMetaData;
|
||||
|
||||
@BeforeMethod
|
||||
@AfterMethod
|
||||
public void cleanup() throws Exception {
|
||||
HashMap<String, String> newEnv = new HashMap<>(System.getenv());
|
||||
newEnv.remove("CHE_DB_TRACING_ENABLED");
|
||||
setEnv(newEnv);
|
||||
lenient().when(dataSource.getConnection()).thenReturn(connection);
|
||||
lenient().when(connection.getMetaData()).thenReturn(databaseMetaData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetConnection() throws SQLException {
|
||||
TracingDataSource ds = new TracingDataSource(dataSource);
|
||||
|
||||
Connection actual = ds.getConnection();
|
||||
assertEquals(actual.getClass(), TracingConnection.class);
|
||||
Mockito.verify(dataSource, Mockito.times(2)).getConnection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToGetConnectionWithEmailAndPassword() throws SQLException {
|
||||
TracingDataSource ds = new TracingDataSource(dataSource);
|
||||
|
||||
Connection actual = ds.getConnection("user", "password");
|
||||
assertEquals(actual.getClass(), TracingConnection.class);
|
||||
Mockito.verify(dataSource).getConnection(Mockito.eq("user"), Mockito.eq("password"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleTogetTracingDataSource() throws Exception {
|
||||
setEnv(ImmutableMap.of("CHE_DB_TRACING_ENABLED", "true"));
|
||||
|
||||
DataSource actual = TracingDataSource.wrapWithTracingIfEnabled(dataSource);
|
||||
|
||||
assertEquals(actual.getClass(), TracingDataSource.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotWrapDatasourceIfEnvSetToFalseØ() throws Exception {
|
||||
setEnv(ImmutableMap.of("CHE_DB_TRACING_ENABLED", "false"));
|
||||
|
||||
DataSource actual = TracingDataSource.wrapWithTracingIfEnabled(dataSource);
|
||||
|
||||
assertEquals(actual, dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotWrapDatasourceIfEnvIsNotSet() throws Exception {
|
||||
DataSource actual = TracingDataSource.wrapWithTracingIfEnabled(dataSource);
|
||||
|
||||
assertEquals(actual, dataSource);
|
||||
}
|
||||
|
||||
protected static void setEnv(Map<String, String> newenv) throws Exception {
|
||||
try {
|
||||
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
|
||||
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
|
||||
theEnvironmentField.setAccessible(true);
|
||||
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
|
||||
env.putAll(newenv);
|
||||
Field theCaseInsensitiveEnvironmentField =
|
||||
processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
|
||||
theCaseInsensitiveEnvironmentField.setAccessible(true);
|
||||
Map<String, String> cienv =
|
||||
(Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
|
||||
cienv.putAll(newenv);
|
||||
} catch (NoSuchFieldException e) {
|
||||
Class[] classes = Collections.class.getDeclaredClasses();
|
||||
Map<String, String> env = System.getenv();
|
||||
for (Class cl : classes) {
|
||||
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
|
||||
Field field = cl.getDeclaredField("m");
|
||||
field.setAccessible(true);
|
||||
Object obj = field.get(env);
|
||||
Map<String, String> map = (Map<String, String>) obj;
|
||||
map.clear();
|
||||
map.putAll(newenv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,353 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.sql.DataSource;
|
||||
import org.eclipse.che.commons.lang.IoUtil;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializationException;
|
||||
import org.eclipse.che.core.db.schema.SchemaInitializer;
|
||||
import org.flywaydb.core.internal.util.PlaceholderReplacer;
|
||||
import org.h2.jdbcx.JdbcDataSource;
|
||||
import org.h2.tools.RunScript;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link FlywaySchemaInitializer}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class FlywaySchemaInitializerTest {
|
||||
|
||||
private static final String SCRIPTS_ROOT = "flyway/sql";
|
||||
|
||||
private JdbcDataSource dataSource;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() throws URISyntaxException {
|
||||
dataSource = new JdbcDataSource();
|
||||
dataSource.setUrl("jdbc:h2:mem:flyway_test;DB_CLOSE_DELAY=-1");
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() throws SQLException, URISyntaxException {
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
RunScript.execute(conn, new StringReader("SHUTDOWN"));
|
||||
}
|
||||
IoUtil.deleteRecursive(targetDir().resolve(Paths.get(SCRIPTS_ROOT)).toFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializesSchemaWhenDatabaseIsEmpty() throws Exception {
|
||||
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
|
||||
createScript(
|
||||
"1.0/2__add_data.sql",
|
||||
"INSERT INTO test VALUES(1, 'test1');"
|
||||
+ "INSERT INTO test VALUES(2, 'test2');"
|
||||
+ "INSERT INTO test VALUES(3, 'test3');");
|
||||
createScript("2.0/1__add_more_data.sql", "INSERT INTO test VALUES(4, 'test4');");
|
||||
createScript(
|
||||
"2.0/postgresql/1__add_more_data.sql", "INSERT INTO test VALUES(4, 'postgresql-data');");
|
||||
|
||||
final SchemaInitializer initializer = FlywayInitializerBuilder.from(dataSource).build();
|
||||
initializer.init();
|
||||
|
||||
assertEquals(
|
||||
queryEntities(),
|
||||
Sets.newHashSet(
|
||||
new TestEntity(1, "test1"),
|
||||
new TestEntity(2, "test2"),
|
||||
new TestEntity(3, "test3"),
|
||||
new TestEntity(4, "test4")));
|
||||
|
||||
// second init must do nothing, so there are no conflicts
|
||||
initializer.init();
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SchemaInitializationException.class)
|
||||
public void failsIfBaseLineIsNotConfiguredProperly() throws Exception {
|
||||
execQuery(
|
||||
"CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));"
|
||||
+ "INSERT INTO test VALUES(1, 'test1');"
|
||||
+ "INSERT INTO test VALUES(2, 'test2');"
|
||||
+ "INSERT INTO test VALUES(3, 'test3');");
|
||||
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
|
||||
|
||||
FlywayInitializerBuilder.from(dataSource)
|
||||
.setBaselineOnMigrate(true)
|
||||
.setBaselineVersion("1.0")
|
||||
.build()
|
||||
.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executesOnlyThoseMigrationsWhichGoAfterBaseline() throws Exception {
|
||||
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
|
||||
createScript(
|
||||
"2.0/1__add_data.sql",
|
||||
"INSERT INTO test VALUES(1, 'test1');"
|
||||
+ "INSERT INTO test VALUES(2, 'test2');"
|
||||
+ "INSERT INTO test VALUES(3, 'test3');");
|
||||
final FlywaySchemaInitializer initializer =
|
||||
FlywayInitializerBuilder.from(dataSource)
|
||||
.setBaselineOnMigrate(true)
|
||||
.setBaselineVersion("1.0.1")
|
||||
.build();
|
||||
|
||||
initializer.init();
|
||||
|
||||
assertEquals(
|
||||
queryEntities(),
|
||||
Sets.newHashSet(
|
||||
new TestEntity(1, "test1"), new TestEntity(2, "test2"), new TestEntity(3, "test3")));
|
||||
|
||||
// second init must do nothing, so there are no conflicts
|
||||
initializer.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializesSchemaWhenDatabaseIsEmptyAndBaselineIsConfigured() throws Exception {
|
||||
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
|
||||
createScript(
|
||||
"2.0/1__add_data.sql",
|
||||
"INSERT INTO test VALUES(1, 'test1');"
|
||||
+ "INSERT INTO test VALUES(2, 'test2');"
|
||||
+ "INSERT INTO test VALUES(3, 'test3');");
|
||||
|
||||
final FlywaySchemaInitializer initializer =
|
||||
FlywayInitializerBuilder.from(dataSource)
|
||||
.setBaselineOnMigrate(true)
|
||||
.setBaselineVersion("1.0.1")
|
||||
.build();
|
||||
initializer.init();
|
||||
|
||||
assertEquals(
|
||||
queryEntities(),
|
||||
Sets.newHashSet(
|
||||
new TestEntity(1, "test1"), new TestEntity(2, "test2"), new TestEntity(3, "test3")));
|
||||
|
||||
// second init must do nothing, so there are no conflicts
|
||||
initializer.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectsProviderSpecificScriptsInPreferenceToDefaultOnes() throws Exception {
|
||||
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
|
||||
createScript("2.0/1__add_data.sql", "INSERT INTO test VALUES(1, 'default data');");
|
||||
createScript("2.0/h2/1__add_data.sql", "INSERT INTO test VALUES(1, 'h2 data');");
|
||||
|
||||
final FlywaySchemaInitializer initializer = FlywayInitializerBuilder.from(dataSource).build();
|
||||
initializer.init();
|
||||
|
||||
assertEquals(queryEntities(), Sets.newHashSet(new TestEntity(1, "h2 data")));
|
||||
|
||||
// second init must do nothing, so there are no conflicts
|
||||
initializer.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void replacesVariablesWhenPlaceholderReplacerIsConfigured() throws Exception {
|
||||
createScript(
|
||||
"1.0/1__init.sql",
|
||||
"CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));"
|
||||
+ "INSERT INTO test VALUES(1, '${variable}');");
|
||||
|
||||
FlywayInitializerBuilder.from(dataSource)
|
||||
.setReplacer(new PlaceholderReplacer(ImmutableMap.of("variable", "test"), "${", "}"))
|
||||
.build()
|
||||
.init();
|
||||
|
||||
assertEquals(queryEntities(), Sets.newHashSet(new TestEntity(1, "test")));
|
||||
}
|
||||
|
||||
private Set<TestEntity> queryEntities() throws SQLException {
|
||||
final Set<TestEntity> entities = new HashSet<>();
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
final ResultSet result = RunScript.execute(conn, new StringReader("SELECT * FROM test"));
|
||||
while (result.next()) {
|
||||
entities.add(new TestEntity(result.getLong("id"), result.getString("text")));
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
private ResultSet execQuery(String query) throws SQLException {
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
return RunScript.execute(conn, new StringReader(query));
|
||||
}
|
||||
}
|
||||
|
||||
private static Path createScript(String relativePath, String content)
|
||||
throws URISyntaxException, IOException {
|
||||
return createFile(
|
||||
targetDir().resolve(Paths.get(SCRIPTS_ROOT)).resolve(relativePath).toString(), content);
|
||||
}
|
||||
|
||||
private static Path createFile(String filepath, String content)
|
||||
throws URISyntaxException, IOException {
|
||||
final Path path = targetDir().resolve(Paths.get(filepath));
|
||||
if (!Files.exists(path.getParent())) {
|
||||
Files.createDirectories(path.getParent());
|
||||
}
|
||||
Files.write(path, content.getBytes(StandardCharsets.UTF_8));
|
||||
return path;
|
||||
}
|
||||
|
||||
private static Path targetDir() throws URISyntaxException {
|
||||
final URL url = Thread.currentThread().getContextClassLoader().getResource(".");
|
||||
assertNotNull(url);
|
||||
return Paths.get(url.toURI()).getParent();
|
||||
}
|
||||
|
||||
private static class TestEntity {
|
||||
final long id;
|
||||
final String text;
|
||||
|
||||
private TestEntity(long id, String text) {
|
||||
this.id = id;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof TestEntity)) {
|
||||
return false;
|
||||
}
|
||||
final TestEntity that = (TestEntity) obj;
|
||||
return id == that.id && Objects.equals(text, that.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 31 * hash + Long.hashCode(id);
|
||||
hash = 31 * hash + Objects.hashCode(text);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TestEntity{" + "id=" + id + ", text='" + text + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
private static class FlywayInitializerBuilder {
|
||||
|
||||
public static FlywayInitializerBuilder from(DataSource dataSource) {
|
||||
try {
|
||||
final String scriptsRoot = targetDir().resolve(Paths.get(SCRIPTS_ROOT)).toString();
|
||||
return new FlywayInitializerBuilder()
|
||||
.setDataSource(dataSource)
|
||||
.setScriptsPrefix("")
|
||||
.setScriptsSuffix(".sql")
|
||||
.setVersionSeparator("__")
|
||||
.setReplacer(PlaceholderReplacer.NO_PLACEHOLDERS)
|
||||
.setBaselineOnMigrate(false)
|
||||
.addLocation("filesystem:" + scriptsRoot);
|
||||
} catch (Exception x) {
|
||||
throw new RuntimeException(x.getMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
private DataSource dataSource;
|
||||
private List<String> locations;
|
||||
private String scriptsPrefix;
|
||||
private String scriptsSuffix;
|
||||
private String versionSeparator;
|
||||
private boolean baselineOnMigrate;
|
||||
private String baselineVersion;
|
||||
private PlaceholderReplacer replacer;
|
||||
|
||||
public FlywayInitializerBuilder setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywayInitializerBuilder setReplacer(PlaceholderReplacer replacer) {
|
||||
this.replacer = replacer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywayInitializerBuilder addLocation(String location) {
|
||||
if (locations == null) {
|
||||
locations = new ArrayList<>();
|
||||
}
|
||||
locations.add(location);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywayInitializerBuilder setScriptsPrefix(String scriptsPrefix) {
|
||||
this.scriptsPrefix = scriptsPrefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywayInitializerBuilder setScriptsSuffix(String scriptsSuffix) {
|
||||
this.scriptsSuffix = scriptsSuffix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywayInitializerBuilder setVersionSeparator(String versionSeparator) {
|
||||
this.versionSeparator = versionSeparator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywayInitializerBuilder setBaselineOnMigrate(boolean baselineOnMigrate) {
|
||||
this.baselineOnMigrate = baselineOnMigrate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywayInitializerBuilder setBaselineVersion(String baselineVersion) {
|
||||
this.baselineVersion = baselineVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FlywaySchemaInitializer build() {
|
||||
if (locations == null) {
|
||||
throw new IllegalStateException("locations required");
|
||||
}
|
||||
return new FlywaySchemaInitializer(
|
||||
locations.toArray(new String[locations.size()]),
|
||||
scriptsPrefix,
|
||||
scriptsSuffix,
|
||||
versionSeparator,
|
||||
baselineOnMigrate,
|
||||
baselineVersion,
|
||||
dataSource,
|
||||
replacer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static com.google.common.collect.Sets.newHashSet;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.flywaydb.core.api.configuration.FlywayConfiguration;
|
||||
import org.flywaydb.core.internal.util.Location;
|
||||
import org.flywaydb.core.internal.util.scanner.Resource;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link ResourcesFinder}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class ResourcesFinderTest {
|
||||
|
||||
private final List<Path> cleanAfter = new ArrayList<>();
|
||||
private final Flyway flyway = new Flyway();
|
||||
|
||||
@BeforeMethod
|
||||
public void setUpDefaults() {
|
||||
flyway.setSqlMigrationSuffix(".sql");
|
||||
flyway.setSqlMigrationPrefix("");
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void cleanup() throws IOException {
|
||||
for (Path path : cleanAfter) {
|
||||
Files.delete(path);
|
||||
}
|
||||
cleanAfter.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsScriptsInClassPath() throws Exception {
|
||||
flyway.setLocations("classpath:finder-sql-files");
|
||||
cleanAfter.addAll(
|
||||
createFiles(
|
||||
"finder-sql-files/1.0/1.sql",
|
||||
"finder-sql-files/1.0/2.sql",
|
||||
"finder-sql-files/2.0/1.sql",
|
||||
"finder-sql-files/2.0/postgresql/1.sql"));
|
||||
|
||||
final Set<String> locations = findResources(flyway).get("classpath:finder-sql-files");
|
||||
|
||||
assertEquals(
|
||||
locations,
|
||||
newHashSet(
|
||||
"finder-sql-files/1.0/1.sql",
|
||||
"finder-sql-files/1.0/2.sql",
|
||||
"finder-sql-files/2.0/1.sql",
|
||||
"finder-sql-files/2.0/postgresql/1.sql"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsScriptsOnFileSystem() throws Exception {
|
||||
final List<Path> paths =
|
||||
createFiles(
|
||||
"finder-sql-files/1.0/1.sql",
|
||||
"finder-sql-files/1.0/2.sql",
|
||||
"finder-sql-files/2.0/1.sql",
|
||||
"finder-sql-files/2.0/postgresql/1.sql");
|
||||
cleanAfter.addAll(paths);
|
||||
final Path finderSqlFiles = paths.get(0).getParent().getParent();
|
||||
final String fsLocation = "filesystem:" + finderSqlFiles.toAbsolutePath();
|
||||
flyway.setLocations(fsLocation);
|
||||
|
||||
final Set<String> locations = findResources(flyway).get(fsLocation);
|
||||
|
||||
assertEquals(
|
||||
locations,
|
||||
newHashSet(
|
||||
finderSqlFiles.resolve("1.0").resolve("1.sql").toString(),
|
||||
finderSqlFiles.resolve("1.0").resolve("2.sql").toString(),
|
||||
finderSqlFiles.resolve("2.0").resolve("1.sql").toString(),
|
||||
finderSqlFiles.resolve("2.0").resolve("postgresql").resolve("1.sql").toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsFileSystemAndClassPathScripts() throws Exception {
|
||||
final List<Path> paths =
|
||||
createFiles(
|
||||
"finder-fs-sql-files/1.0/1.sql",
|
||||
"finder-fs-sql-files/2.0/2.sql",
|
||||
"finder-cp-sql-files/1.0/2.sql",
|
||||
"finder-cp-sql-files/2.0/postgresql/1.sql");
|
||||
cleanAfter.addAll(paths);
|
||||
final Path finderFsSqlFiles = paths.get(0).getParent().getParent();
|
||||
final String fsLocation = "filesystem:" + finderFsSqlFiles.toAbsolutePath();
|
||||
final String cpLocation = "classpath:finder-cp-sql-files";
|
||||
flyway.setLocations(fsLocation, cpLocation);
|
||||
|
||||
final Map<String, Set<String>> locations = findResources(flyway);
|
||||
|
||||
assertEquals(
|
||||
locations.get(fsLocation),
|
||||
newHashSet(
|
||||
finderFsSqlFiles.resolve("1.0").resolve("1.sql").toString(),
|
||||
finderFsSqlFiles.resolve("2.0").resolve("2.sql").toString()));
|
||||
assertEquals(
|
||||
locations.get(cpLocation),
|
||||
newHashSet("finder-cp-sql-files/1.0/2.sql", "finder-cp-sql-files/2.0/postgresql/1.sql"));
|
||||
}
|
||||
|
||||
private static Map<String, Set<String>> findResources(FlywayConfiguration configuration)
|
||||
throws IOException {
|
||||
final Map<Location, List<Resource>> resources =
|
||||
new ResourcesFinder().findResources(configuration);
|
||||
final Map<String, Set<String>> locations = new HashMap<>();
|
||||
for (Map.Entry<Location, List<Resource>> entry : resources.entrySet()) {
|
||||
locations.put(
|
||||
entry.getKey().toString(),
|
||||
entry.getValue().stream().map(Resource::getLocation).collect(Collectors.toSet()));
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
private static List<Path> createFiles(String... paths) throws URISyntaxException, IOException {
|
||||
final URL url = Thread.currentThread().getContextClassLoader().getResource(".");
|
||||
assertNotNull(url);
|
||||
final Path classesDir = Paths.get(url.toURI());
|
||||
final List<Path> createdFiles = new ArrayList<>(paths.length);
|
||||
for (String stringPath : paths) {
|
||||
final Path path = classesDir.resolve(Paths.get(stringPath));
|
||||
if (!Files.exists(path.getParent())) {
|
||||
Files.createDirectories(path.getParent());
|
||||
}
|
||||
Files.write(path, path.toString().getBytes(StandardCharsets.UTF_8));
|
||||
createdFiles.add(path);
|
||||
}
|
||||
return createdFiles;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
import org.flywaydb.core.api.FlywayException;
|
||||
import org.flywaydb.core.internal.util.Location;
|
||||
import org.flywaydb.core.internal.util.scanner.Resource;
|
||||
import org.flywaydb.core.internal.util.scanner.filesystem.FileSystemResource;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link SqlScriptCreator}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class SqlScriptCreatorTest {
|
||||
|
||||
@Test
|
||||
public void createsScript() throws Exception {
|
||||
final Location location = new Location("filesystem:schema");
|
||||
final Resource resource = new FileSystemResource("schema/5.0.0-M7/v1__init.sql");
|
||||
|
||||
final SqlScriptCreator scriptsCreator = new SqlScriptCreator();
|
||||
final SqlScript script = scriptsCreator.createScript(location, resource);
|
||||
|
||||
assertEquals(script.name, "v1__init.sql");
|
||||
assertEquals(script.location, location);
|
||||
assertEquals(script.dir, "5.0.0-M7");
|
||||
assertEquals(script.resource.getLocation(), resource.getLocation());
|
||||
assertNull(script.vendor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createsVendorScript() throws Exception {
|
||||
final Location location = new Location("filesystem:schema");
|
||||
final Resource resource = new FileSystemResource("schema/5.0.0-M7/postgresql/v1__init.sql");
|
||||
|
||||
final SqlScriptCreator scriptsCreator = new SqlScriptCreator();
|
||||
final SqlScript script = scriptsCreator.createScript(location, resource);
|
||||
|
||||
assertEquals(script.name, "v1__init.sql");
|
||||
assertEquals(script.location, location);
|
||||
assertEquals(script.dir, "5.0.0-M7");
|
||||
assertEquals(script.resource.getLocation(), resource.getLocation());
|
||||
assertEquals(script.vendor, "postgresql");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = FlywayException.class)
|
||||
public void failsToCreateResourceWhenPathIsInvalid() throws Exception {
|
||||
final Location location = new Location("filesystem:schema");
|
||||
final Resource resource = new FileSystemResource("schema/v1__init.sql");
|
||||
|
||||
new SqlScriptCreator().createScript(location, resource);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.core.db.schema.impl.flyway;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.flywaydb.core.api.FlywayException;
|
||||
import org.flywaydb.core.api.MigrationVersion;
|
||||
import org.flywaydb.core.internal.util.Location;
|
||||
import org.flywaydb.core.internal.util.scanner.filesystem.FileSystemResource;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link VersionResolver}.
|
||||
*
|
||||
* @author Yevhenii Voevodin
|
||||
*/
|
||||
public class VersionResolverTest {
|
||||
|
||||
private final Flyway flyway = new Flyway();
|
||||
private final VersionResolver resolver = new VersionResolver();
|
||||
|
||||
@BeforeMethod
|
||||
public void setUpDefaults() {
|
||||
flyway.setSqlMigrationSuffix(".sql");
|
||||
flyway.setSqlMigrationPrefix("");
|
||||
flyway.setSqlMigrationSeparator("__");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validScripts")
|
||||
public void resolvesVersion(String dir, String name, String expectedVersion) {
|
||||
final SqlScript script =
|
||||
new SqlScript(
|
||||
new FileSystemResource("sql/" + dir + "/" + name),
|
||||
new Location("filesystem:sql"),
|
||||
dir,
|
||||
null,
|
||||
name);
|
||||
|
||||
assertEquals(resolver.resolve(script, flyway), MigrationVersion.fromVersion(expectedVersion));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidScripts", expectedExceptions = FlywayException.class)
|
||||
public void failsToResolveVersions(String dir, String name) throws Exception {
|
||||
final SqlScript script =
|
||||
new SqlScript(
|
||||
new FileSystemResource("sql/" + dir + "/" + name),
|
||||
new Location("filesystem:sql"),
|
||||
dir,
|
||||
null,
|
||||
name);
|
||||
resolver.resolve(script, flyway);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] invalidScripts() {
|
||||
return new String[][] {
|
||||
{"1.0", "2016-11-11__init.sql"},
|
||||
{"1.0", "one__init.sql"},
|
||||
{"1.0", "__init.sql"},
|
||||
{"1.0", "version1__script.sql"},
|
||||
{"1.0", "1..1__script.sql"},
|
||||
{"5..0.0", "1__init.sql"}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] validScripts() {
|
||||
return new Object[][] {
|
||||
{"5.0.0-M7", "1__init.sql", "5.0.0.7.1"},
|
||||
{"5.0.0-M7", "1.1__init_sub_tables.sql", "5.0.0.7.1.1"},
|
||||
{"6.0", "0.1__specific_update.sql", "6.0.0.1"},
|
||||
{"1.0", "1__simple.sql", "1.0.1"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
This program and the accompanying materials are made
|
||||
available under the terms of the Eclipse Public License 2.0
|
||||
which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
||||
SPDX-License-Identifier: EPL-2.0
|
||||
|
||||
Contributors:
|
||||
Red Hat, Inc. - initial API and implementation
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="file" class="ch.qos.logback.core.FileAppender">
|
||||
<File>target/log/codenvy.log</File>
|
||||
<encoder>
|
||||
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="ERROR">
|
||||
<appender-ref ref="stdout"/>
|
||||
<appender-ref ref="file"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
--
|
||||
-- Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
-- This program and the accompanying materials are made
|
||||
-- available under the terms of the Eclipse Public License 2.0
|
||||
-- which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
--
|
||||
-- SPDX-License-Identifier: EPL-2.0
|
||||
--
|
||||
-- Contributors:
|
||||
-- Red Hat, Inc. - initial API and implementation
|
||||
--
|
||||
|
||||
CREATE TABLE test (
|
||||
id INT,
|
||||
text TEXT,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
--
|
||||
-- Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
-- This program and the accompanying materials are made
|
||||
-- available under the terms of the Eclipse Public License 2.0
|
||||
-- which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
--
|
||||
-- SPDX-License-Identifier: EPL-2.0
|
||||
--
|
||||
-- Contributors:
|
||||
-- Red Hat, Inc. - initial API and implementation
|
||||
--
|
||||
|
||||
INSERT INTO test VALUES(1, 'test1');
|
||||
INSERT INTO test VALUES(2, 'test2');
|
||||
INSERT INTO test VALUES(3, 'test3');
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
--
|
||||
-- Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
-- This program and the accompanying materials are made
|
||||
-- available under the terms of the Eclipse Public License 2.0
|
||||
-- which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
--
|
||||
-- SPDX-License-Identifier: EPL-2.0
|
||||
--
|
||||
-- Contributors:
|
||||
-- Red Hat, Inc. - initial API and implementation
|
||||
--
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue