package org.vaadin.mideaas.frontend; import org.vaadin.mideaas.model.*; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import org.vaadin.mideaas.frontend.Deployer.DeployListener; import org.vaadin.mideaas.model.SharedProject; import org.vaadin.mideaas.model.User; import org.vaadin.mideaas.model.UserSettings; import com.github.wolfie.refresher.Refresher; import com.vaadin.server.ExternalResource; import com.vaadin.server.RequestHandler; import com.vaadin.server.ThemeResource; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinResponse; import com.vaadin.server.VaadinSession; import com.vaadin.ui.Alignment; import com.vaadin.ui.BrowserFrame; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.Embedded; import com.vaadin.ui.Label; import com.vaadin.ui.Link; import com.vaadin.ui.Notification; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.Panel; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.Reindeer; import fi.jasoft.qrcode.QRCode; @SuppressWarnings("serial") public class DeployComponent extends CustomComponent implements DeployListener { // IP address of the chosen server (on map application) by user private String ipOfPlaceOfDeploy = null; private final Deployer deployer; private final SharedProject project; private final UserSettings settings; private final LogView logView = new LogView(); private CFAppsView view; private UI ui; private VerticalLayout layout = new VerticalLayout(); private VerticalLayout resultLayout = new VerticalLayout(); private QRCode qrCode = new QRCode(); private Link linkToApp = new Link("Link To App", null); // after calling deployApplication Rest method of COAPS API, it takes a little time // (I don't know why) for application (written by user) to be deployed. When deployment is done and // application is ready to run, this flag will be true. private static boolean isDeployed = false; // a link button to check whether the application (written by user) is deployed and ready to run or not private Button buttonLinkToApp = new Button("Link To App"); // the URL where the application (written by user) is deployed private static String uriToService = null; final private Button deployButton = new Button("Deploy app"); private Label paasNameLabel = new Label(); //final private Button cancelButton = new Button("Cancel"); final private Button stopButton = new Button("Delete all apps"); final private Button showButton = new Button("Show all apps"); final private Button showLogButton = new ShowLogButton("XMLMessage Log", logView); private Embedded loadingImg = new Embedded(null, new ThemeResource( "../base/common/img/loading-indicator.gif")); protected String responseMessage = null; private Button slabutton = null; private Button showResponseDataButton = null; private User user = null; public DeployComponent(SharedProject project, UserSettings settings, User user) { super(); this.user = user; ipOfPlaceOfDeploy = "http://130.230.142.89:8080/CF-api/rest"; uriToService = null; isDeployed = false; this.project = project; this.settings=settings; String pathToWar = new File(project.getTargetPathFor(user).getAbsolutePath(), project.getName()+".war").getAbsolutePath(); this.deployer = new Deployer(pathToWar, settings.coapsApiUri, this.linkToApp, this.buttonLinkToApp, ipOfPlaceOfDeploy, user, deployButton); //System.out.println("ipOfPlaceOfDeploy from DeployComponent: " + deployer.getApiLocation()); } public static boolean isDeployed() { return isDeployed; } public static void setDeployed(boolean isDeployed) { DeployComponent.isDeployed = isDeployed; } public static String getUriToService() { return uriToService; } private void buildLayout() { Panel p = new Panel("CloudFoundry panel"); p.setContent(layout); layout.setSpacing(true); paasNameLabel.setValue("TAMPERE UNIVERSITY OF TECHNOLOGY"); layout.addComponent(paasNameLabel); //TODO: add stuff here if (settings.useSlaSelectionMap){ createSLANavigationFeatures(); } layout.addComponent(deployButton); deployButton.setDescription("To Tampere University Of Technology"); //layout for showing deployment results layout.addComponent(resultLayout); loadingImg.setVisible(false); layout.addComponent(loadingImg); //cancelButton.setVisible(false); //layout.addComponent(cancelButton); layout.addComponent(showButton); layout.addComponent(stopButton); layout.addComponent(showLogButton); //adds qr code qrCode.setVisible(false); qrCode.setWidth("128px"); qrCode.setHeight("128px"); layout.addComponent(qrCode); //link to the deployed application linkToApp.setVisible(false); layout.setMargin(true); layout.addComponent(linkToApp); // a link button to check whether the application (written by user) is deployed and ready to run or not buttonLinkToApp.setVisible(false); buttonLinkToApp.setStyleName(Reindeer.BUTTON_LINK); layout.addComponent(buttonLinkToApp); setCompositionRoot(p); // set the alignment of component to center both vertically and horizontally layout.setComponentAlignment(deployButton, Alignment.MIDDLE_CENTER); //layout.setComponentAlignment(cancelButton, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(showButton, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(stopButton, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(showLogButton, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(loadingImg, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(qrCode, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(linkToApp, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(buttonLinkToApp, Alignment.MIDDLE_CENTER); //buttonhandlers this.deployButton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { deploy(); } }); /* this.cancelButton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { cancelDeploy(); networkingCancelled("Deploy cancelled"); } }); */ this.stopButton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { deleteAppsUsingPAASAPI(); } }); this.showButton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { findAppsInPAASAPI(); } }); // a link button to check whether the application (written by user) is deployed or not: // 1- if not, it notifies user that s/he should wait and try later // 2- if yes, make the link button invisible and instead make a link (Vaadin component) // (to the deployed application) visible. this.buttonLinkToApp.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { // TODO Auto-generated method stub if (uriToService != null) { try { URL url = new URL(uriToService); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); int returnCode = connection.getResponseCode(); if (returnCode == 200) { //ui.getPage().open(uriToService, "_blank"); setDeployed(true); //Notification.show("Your application is deployed. Press the link one more time and enjoy!"); Notification.show("It takes a little time for your application to be deployed (around one minute)!\n Please try later."); buttonLinkToApp.setVisible(false); linkToApp.setResource(new ExternalResource(uriToService)); linkToApp.setTargetName("_blank"); linkToApp.setVisible(true); } else { Notification.show("It takes a little time for your application to be deployed (around one minute)!\n Please try later."); } } catch (Exception e) {} } } }); } private void createSLANavigationFeatures() { slabutton = new Button("Negotiate SLA"); layout.addComponent(slabutton); layout.setComponentAlignment(slabutton, Alignment.MIDDLE_CENTER); showResponseDataButton = new Button("ShowResponseData"); showResponseDataButton.setEnabled(false); layout.addComponent(showResponseDataButton); layout.setComponentAlignment(showResponseDataButton, Alignment.MIDDLE_CENTER); slabutton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { // Strange!!! it needs a refresher to synchronize UI final Refresher r = new Refresher(); r.addListener(new Refresher.RefreshListener() { @Override public void refresh(Refresher source) { // TODO Auto-generated method stub removeExtension(r); } }); addExtension(r); ipOfPlaceOfDeploy = null; showResponseDataButton.setEnabled(false); String params = "/cloud?callbackUri=http://130.230.142.89:8080/mideaastest"; //String params = "/cloud?callbackUri=http://localhost:8080/mideaas"; // opening map application in a sub-window added to current UI final Window mapSubWindow = new Window(); mapSubWindow.setModal(true); mapSubWindow.setHeight("90%"); mapSubWindow.setWidth("70%"); mapSubWindow.center(); VerticalLayout mapSubWindowLayout = new VerticalLayout(); mapSubWindow.setContent(mapSubWindowLayout); mapSubWindowLayout.setSizeFull(); BrowserFrame mapBrowserFrame = new BrowserFrame("",new ExternalResource(settings.slaSelectionMapUri + params)); mapSubWindowLayout.addComponent(mapBrowserFrame); mapBrowserFrame.setSizeFull(); UI.getCurrent().addWindow(mapSubWindow); // add a request handler to get callback URL VaadinSession.getCurrent().addRequestHandler(new RequestHandler() { @Override public boolean handleRequest( VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { // TODO Auto-generated method stub VaadinSession.getCurrent().removeRequestHandler(this); String paasName = request.getParameter("PaasName"); ipOfPlaceOfDeploy = request.getParameter("selectedPaas"); if(ipOfPlaceOfDeploy != null && paasName != null) { //CoapsCaller.setApiLocation(ipOfPlaceOfDeploy + "rest"); paasNameLabel.setValue(paasName); deployer.setApiLocation(ipOfPlaceOfDeploy + "rest"); deployer.checkIFSomeoneIsDeploying(resultLayout, qrCode, loadingImg); showResponseDataButton.setEnabled(true); mapSubWindow.close(); showPlaceOfDeployment(paasName); } return false; } }); } }); //buttonhandlers this.showResponseDataButton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { Notification.show(ipOfPlaceOfDeploy); } }); } private void showPlaceOfDeployment(String paasName) { Notification notif = new Notification( paasName, "is chosen", Type.TRAY_NOTIFICATION); notif.setDelayMsec(2000); notif.show(ui.getPage()); deployButton.setDescription("To " + paasName); } @Override public void attach() { super.attach(); buildLayout(); setUi(UI.getCurrent()); deployer.addDeployListener(this); System.out.println(user.getName() + "add to list"); //StartOfDeploymentBroadcaster.register(this); deployer.checkIFSomeoneIsDeploying(resultLayout, qrCode, loadingImg); } @Override public void detach() { super.detach(); deployer.removeDeployListener(this); System.out.println(user.getName() + "removed from list"); //StartOfDeploymentBroadcaster.unregister(this); } private synchronized void setUi(UI ui) { this.ui = ui; } private synchronized UI getUi() { return ui; } public void cancelDeploy() { deployer.cancel(); } private void deploy() { //StartOfDeploymentBroadcaster.unregister(this); deployer.deploy(this.settings, this.project, this.logView, this.buttonLinkToApp, this.qrCode); //StartOfDeploymentBroadcaster.register(this); this.updateCFAppsView(); } private void finishDeploy() { loadingImg.setVisible(false); deployButton.setEnabled(true); //deployButton.setCaption("Deploy"); //cancelButton.setVisible(false); } private void deployFail(String s) { Label lab = new Label(s); lab.setIcon(Icons.CROSS_CIRCLE); lab.setSizeUndefined(); resultLayout.addComponent(lab); resultLayout.setComponentAlignment(lab, Alignment.MIDDLE_CENTER); } private void deploySuccess() { Label lab = new Label("Deploy successful"); lab.setIcon(Icons.TICK_CIRCLE); lab.setSizeUndefined(); resultLayout.addComponent(lab); resultLayout.setComponentAlignment(lab, Alignment.MIDDLE_CENTER); } @Override public void networkingFinished(final boolean success, final String msg, final String UriToServic) { getUi().access(new Runnable() { @Override public void run() { finishDeploy(); uriToService = UriToServic; if (success) { deploySuccess(); } else { deployFail(msg); qrCode.setVisible(false); linkToApp.setVisible(false); buttonLinkToApp.setVisible(false); } } }); } @Override public void networkingCancelled(final String msg) { getUi().access(new Runnable() { @Override public void run() { finishDeploy(); deployFail(msg); qrCode.setVisible(false); linkToApp.setVisible(false); buttonLinkToApp.setVisible(false); } }); } @Override public void networkingStarted(final String msg) { getUi().access(new Runnable() { @Override public void run() { resultLayout.removeAllComponents(); deployButton.setEnabled(false); //cancelButton.setVisible(true); loadingImg.setVisible(true); loadingImg.setCaption(msg); linkToApp.setVisible(false); buttonLinkToApp.setVisible(false); qrCode.setVisible(false); setDeployed(false); } }); } //deletes all the environments and applications (mainly because of testing purposes... Should be disabled later) private void deleteAppsUsingPAASAPI() { logView.newLine("Deletes applications running"); String xml = deployer.deleteApplications(); logView.newLine(xml); logView.newLine("Deletes environments"); if(deployer.deleteEnvironments(logView)){ linkToApp.setVisible(false); buttonLinkToApp.setVisible(false); qrCode.setVisible(false); deployFail("Apps deleted"); } updateCFAppsView(); } private void updateCFAppsView() { if (view!=null){ view.updateView(); } } private void findAppsInPAASAPI() { logView.newLine("Gets applications running"); view = new CFAppsView(deployer, logView); Window w = new Window("Applications running in CloudFoundry"); w.center(); w.setWidth("80%"); w.setHeight("80%"); w.setContent(view); view.setSizeFull(); UI.getCurrent().addWindow(w); } /* @Override public void deployStartted(final String apiLocation, final String appName, final User deployerUser) { ui.access(new Runnable() { @Override public void run() { // TODO Auto-generated method stub if(deployerUser.getUserId().matches(user.getUserId())) { // do nothing } else if(deployer.getApiLocation().matches(apiLocation) && appName.matches(project.getName()) ) { deployButton.setEnabled(false); //System.out.println(user.getName() + " start" ); resultLayout.removeAllComponents(); buttonLinkToApp.setVisible(false); linkToApp.setVisible(false); qrCode.setVisible(false); loadingImg.setVisible(true); loadingImg.setCaption(deployerUser.getName() + " is deploying"); Notification notif = new Notification( deployerUser.getName(), Type.TRAY_NOTIFICATION); notif.setDelayMsec(1000); notif.setDescription("started deployment"); notif.show(ui.getPage()); } } }); } @Override public void deployFinished(final String apiLocation, final String appName, final User deployerUser) { ui.access(new Runnable() { @Override public void run() { // TODO Auto-generated method stub if(deployerUser.getUserId().matches(user.getUserId())) { // do nothing } else if(deployer.getApiLocation().matches(apiLocation) && appName.matches(project.getName()) ) { deployButton.setEnabled(true); //System.out.println(user.getName() + " start" ); loadingImg.setVisible(false); //loadingImg.setCaption(user.getName() + " finished deploying"); Notification notif = new Notification( deployerUser.getName(), Type.TRAY_NOTIFICATION); notif.setDelayMsec(1000); notif.setDescription("finished deployment"); notif.show(ui.getPage()); } } }); } */ }