Live editing and pair programming with Eclipse Cloud Development top projects Sun TAN @sunsengdavidtan
Serli Société de conseil et d’ingénierie Innovation, Ingénierie, Formation 70 personnes Contribution à des projets OSS Membre du JCP Poitou charentes JUG leader @JUGSummerCamp La Rochelle, 18th September 2015 @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Sun TAN Java Developer My job Location ● ● Java developer Paris, France ○ ○ Eclipse che commiter ○ Team leader ○ @sunsengdavidtan Scrum master ○ http://sunix.org Trainer ○ Previously ● Eclipse RCP developer, ○ Nuxeo, Eclipse Apogee, ○ Eclipse Apricot @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Agenda ● Introduction to Eclipse Flux ● Demo 1 ○ Eclipse Flux running on a Eclipse Che docker runner. ○ Pair programing with Orion and Eclipse IDE ● Demo2: Eclipse Che extension ○ Pair programing with Orion, Eclipse IDE and Che @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Eclipse Flux Eclipse flux ○ By Pivotal ○ Message based architechture ○ Connect developer tools in the Cloud ○ Available demos: https://www.eclipse.org/flux/ ■ Real time live edit ■ (v)fs synchronization ■ Eclipse JDT on Eclipse Orion @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Eclipse Flux Communication Eclipse flux ○ Communication ■ Central NodeJS Web socket (socketio) server ■ Exchanging well known messages between each participant. ■ Request-response model or broadcast ■ Anyone can respond @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Eclipse Flux Websocket Flux Websocket communication (Google Chrome dev tools) @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Eclipse Flux FS sync @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Eclipse flux Eclipse Flux server: ○ NodeJS ○ RabbitMQ ○ Socket.io ○ (Mongo DB) ○ Npm https://github.com/eclipse/flux @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Running Flux in Che Demo Demo 1 ■ Eclipse Flux running on a Eclipse Che docker runner ■ Launch embedded Orion and Eclipse IDE Start to pair program :) @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Running Flux in Che Dockerfile FROM sunix/flux CMD sudo service rabbitmq-server start && npm start @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Running Flux in Che Dockerfile FROM codenvy/jdk7 RUN sudo -E bash -c "echo \"deb http://www.rabbitmq.com/debian/ testing main\" >> /etc/apt/sources.list" RUN sudo wget https://www.rabbitmq.com/rabbitmq-signing-key-public.asc RUN sudo apt-key add rabbitmq-signing-key-public.asc RUN sudo apt-get update RUN sudo apt-get install -y rabbitmq-server nodejs-legacy npm EXPOSE 3000 ENV CODENVY_APP_PORT_3000_HTTP 3000 RUN wget https://github.com/eclipse/flux/archive/master.zip && unzip master.zip RUN sudo npm install ENV VCAP_APP_HOST 0.0.0.0 RUN wget https://gist.githubusercontent. com/sunix/a9a1037e257da5d0a600/raw/3ff8a910f3400d19775bb562c89524518ac6f2d2/startup-all-in-one.js.patch RUN patch -p1 < startup-all-in-one.js.patch CMD sudo service rabbitmq-server start && npm start @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension Demo2 Demo2: Eclipse Che extension ○ Connect che editors to flux ○ Detect running Docker flux runner https://github.com/sunix/che-plugin-flux-live-edit Screen cast of the demo Starting pair programing session as easy as Sharing a Che URL! @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension GWT and socket.io Inject socketio.js SocketIOResources ioresources = GWT. create (SocketIOResources. class ); ScriptInjector. fromString (ioresources.socketIo().getText()).setWindow (ScriptInjector. TOP_WINDOW ).inject(); GWT JSNI and overlay to talk to native javascript public static native SocketIOOverlay getSocketIO()/*-{ return $wnd.io; }-*/; @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension GWT and socket.io Javascript overlay public class SocketOverlay extends JavaScriptObject { protected SocketOverlay() {} public final native void emit(String type, JavaScriptObject json) /*-{ this.emit(type, json, function(answer) {}); }-*/; public final native void on(String eventName, Runnable runnable) /*-{ this.on(eventName, function() { handler.@java.lang.Runnable::run()(); }); }-*/; @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension Connect to flux Connect to flux protected void connectToFlux( ApplicationProcessDescriptor descriptor, String host, String fluxPort) { SocketIOOverlay io = getSocketIO (); String url = "http://" + host + ":" + fluxPort; socket = io.connect(url); socket.emit("connectToChannel", JsonUtils. safeEval ("{\"channel\" : \"USER\"}")); … } @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension Listen to Che runners Listen to Che runners start events eventBus.addHandler(RunnerApplicationStatusEvent. TYPE , runner -> { ApplicationProcessDescriptor descriptor = runner.getDescriptor(); connectIfFluxMicroservice(descriptor); }); private boolean connectIfFluxMicroservice(ApplicationProcessDescriptor descriptor) { String fluxPort = descriptor.getPortMapping().getPorts().get("3000"); if (fluxPort == null ) { return false ; } String host = descriptor.getPortMapping().getHost(); if (descriptor.getStatus() == ApplicationStatus. RUNNING ) { connectToFlux(descriptor, host, fluxPort); return true ; } return false ; } @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension Receive change events Receive change events socket.on("liveResourceChanged", fluxChangedEvent -> { Document document = liveDocuments.get( "/" + fluxChangedEvent.getProject() + "/" + fluxChangedEvent.getResource()); isUpdatingModel = true ; document.replace(fluxChangedEvent.getOffset(), fluxChangedEvent.getRemovedCharCount(), fluxChangedEvent.getAddedCharacters()); isUpdatingModel = false ; } ); @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension Send change events eventBus.addHandler(DocumentReadyEvent. TYPE , docReadyEvent -> { liveDocuments.put(docReadyEvent.getDocument().getFile().getPath(), docReadyEvent.getDocument()); docReadyEvent .getDocument().getDocumentHandle().getDocEventBus() .addHandler(DocumentChangeEvent. TYPE , docChangeEvent -> { String fullPath = docChangeEvent.getDocument().getDocument().getFile().getPath().substring(1); String project = fullPath.substring(0, fullPath.indexOf('/')); String resource = fullPath.substring(fullPath.indexOf('/') + 1); String text = JsonUtils. escapeValue (docChangeEvent.getText()); String json = "{" + "\"username\":\"USER\"," + "\"project\":\"" + project + "\"," + "\"resource\":\"" + resource + "\"," + "\"offset\":" + docChangeEvent.getOffset() + "," + "\"removedCharCount\":" + docChangeEvent.getRemoveCharCount() + "," + "\"addedCharacters\":" + text + "}"; if (isUpdatingModel) { return ; } socket.emit("liveResourceChanged", JsonUtils. unsafeEval (json)); }); }); @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Che extension Connect on open eventBus.addHandler(OpenProjectEvent. TYPE , openProjectEvent -> { runnerService.getRunningProcesses(openProjectEvent.getProjectName(), newAsyncCallback() .success( processes -> { for (ApplicationProcessDescriptor process : processes.asIterable()) { if (connectIfFluxMicroservice(process)) { break ; } } }) .failure(e -> Log. error (GetRunningProcessesAction. class , e)) .build()); }); @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Next ... ● Improve Che extension ○ add messages “live session started” ○ implement (v)fs sync ○ cursor positions ○ actions by other participants ○ chat ● Publish the extension ○ default che packaging ○ add a contribute button to the github project @sunsengdavidtan @serlifr #eclipseche #eclipseflux #orion #eclipse
Recommend
More recommend