Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

Pre-fetching of the default editor CDN resources #1192

Merged
merged 27 commits into from
Jan 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
67568ba
Endpoint to retrieve the up-to-date CDN.json file for the default editor
davidfestal Jan 15, 2019
270fd0e
small fix
davidfestal Jan 15, 2019
aeffa37
Start tests in a forked process
davidfestal Jan 16, 2019
67c2b9a
useSystemClassLoader => true
davidfestal Jan 16, 2019
518620c
troubleshooting logs
davidfestal Jan 16, 2019
46b1c53
Adding test resources
davidfestal Jan 16, 2019
bf3e34a
Add the `tar.gz` test resource and clean the `pom.xml`
davidfestal Jan 16, 2019
c0e2c72
Add missing property
davidfestal Jan 16, 2019
487247d
Fix a small bug in the custom deployment, in order to debug more easily
davidfestal Jan 17, 2019
9a202a9
Add missing new line
davidfestal Jan 17, 2019
db32c3f
clean `system.out` calls
davidfestal Jan 17, 2019
547d00f
safer code
davidfestal Jan 17, 2019
3e0f807
Add myself in the authors
davidfestal Jan 17, 2019
b6a5c32
remove unuseful debugging message
davidfestal Jan 17, 2019
8594506
minor typo
davidfestal Jan 17, 2019
ded8b24
throw instead of returning an empty array in case of errors
davidfestal Jan 17, 2019
353045f
typo
davidfestal Jan 17, 2019
9a69f58
Add examples of the new property
davidfestal Jan 18, 2019
f4e2ec0
typo
davidfestal Jan 18, 2019
d57be5e
Use format instead of concatenation
davidfestal Jan 18, 2019
68e1099
Make the docker image label name more general
davidfestal Jan 18, 2019
da0589e
return empty array instead of empty object
davidfestal Jan 18, 2019
02a8a37
never cache the request to `paths`
davidfestal Jan 18, 2019
5f86c23
Changes proposed by the PR quality review
davidfestal Jan 18, 2019
31a5699
Fixes after @garagatyi comments
davidfestal Jan 21, 2019
9123db6
Fix process output management
davidfestal Jan 22, 2019
25337fa
Add a space, just in case it would be that...
davidfestal Jan 22, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assembly/assembly-wsmaster-war/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
<groupId>com.redhat.che</groupId>
<artifactId>che-plugin-analytics-wsmaster</artifactId>
</dependency>
<dependency>
<groupId>com.redhat.che</groupId>
<artifactId>fabric8-cdn-support</artifactId>
</dependency>
<dependency>
<groupId>com.redhat.che</groupId>
<artifactId>fabric8-end2end-flow</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,11 @@ che.fabric8.end2end.protect.secret_key=NULL
# End2End Flow bot protection: option to enable the use of the client IP
# in the captcha server-side verification
che.fabric8.end2end.protect.verify_with_ip=false

# Full identifier of the default editor whose CDN resources
# should be prefetched during the dashboard client-side load
# - Can be the identifier of an editor plugin in the plugin registry, like that:
# org.eclipse.che.editor.theia:1.0.0
# - or the full path to a custom editor plugin, like that:
# https://raw.githubusercontent.com/davidfestal/che-theia-cdn/master/plugins/org.eclipse.che.editor.theia.david:1.0.2
che.fabric8.cdn.prefetch.editor=NULL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we include an example value here? I don't know offhand what the full identifier would look like.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example added

2 changes: 1 addition & 1 deletion assembly/fabric8-ide-dashboard-war/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
<exec dir="${basedir}/target/sources" executable="npm" failonerror="true">
<arg value="install" />
<arg value="yarn" />
</exec>>
</exec>
</target>
</configuration>
</execution>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2016-2018 Red Hat, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: 2019

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems it's not supported by the license checker for now

* 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
*/
'use strict';
import {CheBranding} from '../branding/che-branding.factory';

const IDE_FETCHER_CALLBACK_ID = 'cheIdeFetcherCallback';

/**
* Provides a way to download IDE .js and then cache it before trying to load the IDE
* @author Florent Benoit
* @author Oleksii Orel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're now an author :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

* @author David Festal
*/
export class CheIdeFetcher {

static $inject = ['$log', '$http', '$window', 'cheBranding'];

private $log: ng.ILogService;
private $http: ng.IHttpService;
private $window: ng.IWindowService;
private cheBranding: CheBranding;
private userAgent: string;

/**
* Default constructor that is using resource injection
*/
constructor($log: ng.ILogService, $http: ng.IHttpService, $window: ng.IWindowService, cheBranding: CheBranding) {
this.$log = $log;
this.$http = $http;
this.$window = $window;
this.cheBranding = cheBranding;

this.userAgent = this.getUserAgent();

const callback = () => {
this.findMappingFile();
this.cheBranding.unregisterCallback(IDE_FETCHER_CALLBACK_ID);
};
this.cheBranding.registerCallback(IDE_FETCHER_CALLBACK_ID, callback.bind(this));
}

/**
* Gets user agent.
* @returns {string}
*/
getUserAgent(): string {
const userAgent = this.$window.navigator.userAgent.toLowerCase();
const docMode = (<any>this.$window.document).documentMode;

if (userAgent.indexOf('webkit') !== -1) {
return 'safari';
} else if (userAgent.indexOf('msie') !== -1) {
if (docMode >= 10 && docMode < 11) {
return 'ie10';
} else if (docMode >= 9 && docMode < 11) {
return 'ie9';
} else if (docMode >= 8 && docMode < 11) {
return 'ie8';
}
} else if (userAgent.indexOf('gecko') !== -1) {
return 'gecko1_8';
}

return 'unknown';
}

/**
* Finds mapping file.
*/
findMappingFile(): void {
// get the content of the compilation mapping file
const randVal = Math.floor((Math.random() * 1000000) + 1);
const resourcesPath = this.cheBranding.getIdeResourcesPath();
if (!resourcesPath) {
this.$log.log('Unable to get IDE resources path');
return;
}

const fileMappingUrl = `${resourcesPath}compilation-mappings.txt?uid=${randVal}`;

this.$http.get(fileMappingUrl).then((response: {data: any}) => {
if (!response || !response.data) {
return;
}
let urlToLoad = this.getIdeUrlMappingFile(response.data);
// load the url
if (angular.isDefined(urlToLoad)) {
this.$log.log('Preloading IDE javascript', urlToLoad);
this.$http.get(urlToLoad, { cache: true});
} else {
this.$log.error('Unable to find the IDE javascript file to cache');
}
}, (error: any) => {
this.$log.log('unable to find compilation mapping file', error);
});

this.$http.get('/api/cdn-support/paths', {cache: false}).then((response: {data: any}) => {
garagatyi marked this conversation as resolved.
Show resolved Hide resolved
if (!response || !response.data) {
return;
}
const data = response.data;
data.forEach((entry) => {
let urlToLoad = entry.cdn;
// load the url
if (angular.isDefined(urlToLoad)) {
this.$log.log('Preloading Theia resource', urlToLoad);
const link = document.createElement("link");
link.rel='prefetch';
link.href=urlToLoad;
document.head.appendChild(link);
} else {
this.$log.error('Unable to find the Theia resource file to cache');
}
});
}, (error: any) => {
this.$log.log('Unable to find Theia CDN resources to cache', error);
});
}

/**
* Gets URL of mapping file.
* @param data {string}
* @returns {string}
*/
getIdeUrlMappingFile(data: string): string {
let mappingFileUrl: string;
let javascriptFileName: string;
const mappings = data.split(new RegExp('^\\n', 'gm'));
const isPasses = mappings.some((mapping: string) => {
const subMappings = mapping.split('\n');
const userAgent = subMappings.find((subMapping: string) => {
return subMapping.startsWith('user.agent ');
}).split(' ')[1];
javascriptFileName = subMappings.find((subMapping: string) => {
return subMapping.endsWith('.cache.js');
});
return javascriptFileName && userAgent && this.userAgent === userAgent;
});
if (isPasses && javascriptFileName) {
mappingFileUrl = this.cheBranding.getIdeResourcesPath() + javascriptFileName;
}

return mappingFileUrl;
}

}
3 changes: 2 additions & 1 deletion dev-scripts/deploy_custom_rh-che.sh
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ CHE_CONFIG_YAML=$(yq ".\"data\".\"CHE_KEYCLOAK_REALM\" = \"NULL\" |
.\"data\".\"che.jdbc.username\" = \"$RH_CHE_JDBC_USERNAME\" |
.\"data\".\"che.jdbc.password\" = \"$RH_CHE_JDBC_PASSWORD\" |
.\"data\".\"che.jdbc.url\" = \"$RH_CHE_JDBC_URL\" |
.\"data\".\"CHE_LOG_LEVEL\" = \"plaintext\" " ${RH_CHE_CONFIG})
.\"data\".\"CHE_LOG_LEVEL\" = \"INFO\" |
.\"data\".\"CHE_LOGS_APPENDERS_IMPL\" = \"plaintext\" " ${RH_CHE_CONFIG})

CHE_CONFIG_YAML=$(echo "$CHE_CONFIG_YAML" | \
yq ".\"data\".\"CHE_HOST\" = \"rhche-$RH_CHE_PROJECT_NAMESPACE.devtools-dev.ext.devshift.net\" |
Expand Down
1 change: 1 addition & 0 deletions dockerfiles/che-fabric8/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ RUN yum -y update && \
curl -sSL "https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-${DOCKER_VERSION}" -o /usr/bin/docker && \
chmod +x /usr/bin/docker && \
yum -y remove openssl && \
yum -y install skopeo \
yum clean all && \
echo "%root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
sed -i 's/Defaults requiretty/#Defaults requiretty/g' /etc/sudoers && \
Expand Down
1 change: 1 addition & 0 deletions openshift/rh-che.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,4 @@ data:
CHE_INFRA_KUBERNETES_SERVICE__ACCOUNT__NAME: "che-workspace"
CHE_WORKSPACE_STORAGE: "/home/user/che/workspaces"
CHE_WORKSPACE_PLUGIN__BROKER_INIT_IMAGE: "eclipse/che-init-plugin-broker:v0.7.1"
CHE_FABRIC8_CDN_PREFETCH_EDITOR: 'NULL'
114 changes: 114 additions & 0 deletions plugins/fabric8-cdn-support/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2016-2018 Red Hat, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2019 🎉

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear it's not supported by the license checker for now

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>fabric8-ide-plugins-parent</artifactId>
<groupId>com.redhat.che</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>fabric8-cdn-support</artifactId>
<name>Fabric8 IDE :: Plugins :: CDN Support</name>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</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-api-workspace</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-shared</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-inject</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-db</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</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>
Loading