Java tutorial
/* * $Id$ * $URL$ * * ==================================================================== * Ikasan Enterprise Integration Platform * * Distributed under the Modified BSD License. * Copyright notice: The copyright for this software and a full listing * of individual contributors are as shown in the packaged copyright.txt * file. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of the ORGANIZATION nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ package org.ikasan.dashboard.ui.monitor.component; import java.util.HashMap; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.log4j.Logger; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; import org.ikasan.dashboard.ui.IkasanUI; import org.ikasan.dashboard.ui.framework.cache.TopologyStateCache; import org.ikasan.dashboard.ui.framework.event.FlowStateEvent; import org.ikasan.dashboard.ui.framework.util.DashboardSessionValueConstants; import org.ikasan.dashboard.ui.topology.panel.TopologyViewPanel; import org.ikasan.dashboard.ui.topology.window.ErrorCategorisationWindow; import org.ikasan.dashboard.ui.topology.window.StartupControlConfigurationWindow; import org.ikasan.dashboard.ui.topology.window.WiretapConfigurationWindow; import org.ikasan.security.service.authentication.IkasanAuthentication; import org.ikasan.topology.model.Flow; import org.ikasan.topology.model.Module; import org.ikasan.topology.model.Server; import org.ikasan.topology.service.TopologyService; import org.tepi.filtertable.FilterTable; import org.vaadin.teemu.VaadinIcons; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.util.IndexedContainer; import com.vaadin.event.Action; import com.vaadin.event.ItemClickEvent; import com.vaadin.event.MouseEvents.ClickEvent; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.server.VaadinService; import com.vaadin.server.VaadinSession; import com.vaadin.shared.MouseEventDetails.MouseButton; import com.vaadin.ui.Alignment; import com.vaadin.ui.Component; import com.vaadin.ui.CssLayout; import com.vaadin.ui.CustomTable; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.MenuBar; import com.vaadin.ui.Tree; import com.vaadin.ui.MenuBar.Command; import com.vaadin.ui.MenuBar.MenuItem; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** * * @author Ikasan Development Team * */ public class MonitorPanel extends Panel implements View, Action.Handler { private static final long serialVersionUID = -3174124965136021440L; private Logger logger = Logger.getLogger(MonitorPanel.class); private final Action START = new Action("Start"); private final Action STOP = new Action("Stop"); private final Action PAUSE = new Action("Pause"); private final Action START_PAUSE = new Action("Start/Pause"); private final Action RESUME = new Action("Resume"); private final Action RESTART = new Action("Re-start"); private final Action[] flowActionsStopped = new Action[] { START, START_PAUSE }; private final Action[] flowActionsStarted = new Action[] { STOP, PAUSE }; private final Action[] flowActionsPaused = new Action[] { STOP, RESUME }; private final Action[] actionsEmpty = new Action[] {}; private TopologyService topologyService; private Server server; private FilterTable filterTable; private IndexedContainer cont; private HashMap<String, String> stateMap; private Label statusLabel = new Label(); /** running state string constant */ private static String RUNNING = "running"; /** stopped state string constant */ private static String STOPPED = "stopped"; /** recovering state string constant */ private static String RECOVERING = "recovering"; /** stoppedInError state string constant */ private static String STOPPED_IN_ERROR = "stoppedInError"; /** paused state string constant */ private static String PAUSED = "paused"; /** * @param topologyService */ public MonitorPanel(TopologyService topologyService, Server server) { super(); this.topologyService = topologyService; this.server = server; EventBus eventBus = ((IkasanUI) UI.getCurrent()).getEventBus(); eventBus.register(this); } public Component buildServerComponent() { Panel component = new Panel(); component.setSizeFull(); component.addStyleName(ValoTheme.PANEL_BORDERLESS); GridLayout layout = new GridLayout(2, 4); layout.setSizeFull(); layout.setMargin(true); Label serverNameLabel = new Label(server.getName()); serverNameLabel.setStyleName(ValoTheme.LABEL_LARGE); serverNameLabel.setWidth("100%"); Label serverDescriptionLabel = new Label(server.getDescription()); serverDescriptionLabel.setWidth("100%"); serverDescriptionLabel.setStyleName(ValoTheme.LABEL_LARGE); Label serverUrlLabel = new Label(server.getUrl() + ":" + server.getPort()); serverUrlLabel.setStyleName(ValoTheme.LABEL_LARGE); serverUrlLabel.setWidth("100%"); layout.addComponent(serverNameLabel, 0, 0); layout.addComponent(serverDescriptionLabel, 0, 1); layout.addComponent(serverUrlLabel, 0, 2); statusLabel.setCaptionAsHtml(true); MonitorIcons icon = MonitorIcons.SERVER; icon.setSizePixels(64); Label serverLabel = new Label(); serverLabel.setCaption(icon.getHtml()); serverLabel.setCaptionAsHtml(true); layout.addComponent(serverLabel, 1, 0, 1, 2); layout.setComponentAlignment(serverLabel, Alignment.MIDDLE_CENTER); layout.addComponent(statusLabel, 0, 3, 1, 3); layout.setComponentAlignment(statusLabel, Alignment.MIDDLE_CENTER); buildFilterTable(); component.setContent(layout); Component contentWrapper = createContentWrapper(component, buildFilterTable()); contentWrapper.addStyleName("top10-revenue"); return contentWrapper; } protected void setStatusLabel() { MonitorIcons icon = MonitorIcons.CHECK_CIRCLE_O; icon.setSizePixels(64); icon.setColor("green"); for (String key : stateMap.keySet()) { for (Module module : server.getModules()) { if (key.startsWith(module.getName())) { String state = this.stateMap.get(key); if (state.equals(STOPPED) || state.equals(RECOVERING) || state.equals(STOPPED_IN_ERROR)) { icon = MonitorIcons.EXCLAMATION_CIRCLE_O; icon.setSizePixels(64); icon.setColor("red"); statusLabel.setCaption(icon.getHtml()); return; } } } } statusLabel.setCaption(icon.getHtml()); } protected Component createContentWrapper(final Component small, final Component large) { final CssLayout slot = new CssLayout(); slot.setWidth("100%"); slot.addStyleName("monitor-panel-slot"); final CssLayout card1 = new CssLayout(); card1.setWidth("100%"); card1.addStyleName(ValoTheme.LAYOUT_CARD); final CssLayout card2 = new CssLayout(); card2.setWidth("100%"); card2.addStyleName(ValoTheme.LAYOUT_CARD); final HorizontalLayout toolbar = new HorizontalLayout(); toolbar.addStyleName("dashboard-panel-toolbar"); toolbar.setWidth("100%"); Label caption = new Label(large.getCaption()); caption.addStyleName(ValoTheme.LABEL_H4); caption.addStyleName(ValoTheme.LABEL_COLORED); caption.addStyleName(ValoTheme.LABEL_NO_MARGIN); large.setCaption(null); MenuBar tools = new MenuBar(); tools.addStyleName(ValoTheme.MENUBAR_BORDERLESS); MenuItem max = tools.addItem("", VaadinIcons.EXPAND, new Command() { @Override public void menuSelected(final MenuItem selectedItem) { if (!slot.getStyleName().contains("max")) { selectedItem.setIcon(FontAwesome.COMPRESS); slot.removeAllComponents(); card2.removeAllComponents(); card2.addComponents(toolbar, large); slot.addComponents(card2); toggleMaximized(slot, true); } else { slot.removeStyleName("max"); selectedItem.setIcon(FontAwesome.EXPAND); toggleMaximized(slot, false); card1.removeAllComponents(); card1.addComponents(toolbar, small); slot.removeAllComponents(); slot.addComponents(card1); } } }); max.setStyleName("icon-only"); MenuItem root = tools.addItem("", VaadinIcons.COG, null); root.addItem("Configure", new Command() { @Override public void menuSelected(final MenuItem selectedItem) { Notification.show("Not implemented in this demo"); } }); root.addSeparator(); root.addItem("Close", new Command() { @Override public void menuSelected(final MenuItem selectedItem) { Notification.show("Not implemented in this demo"); } }); toolbar.addComponents(caption, tools); toolbar.setExpandRatio(caption, 1); toolbar.setComponentAlignment(caption, Alignment.MIDDLE_LEFT); card1.addComponents(toolbar, small); // card2.addComponents(toolbar, large); slot.addComponent(card1); return slot; } protected FilterTable buildFilterTable() { this.filterTable = new FilterTable(this.server.getName() + " Flow States"); filterTable.setSizeFull(); filterTable.setContainerDataSource(buildContainer()); filterTable.setFilterBarVisible(true); filterTable.addStyleName(ValoTheme.TABLE_BORDERLESS); filterTable.addStyleName(ValoTheme.TABLE_NO_STRIPES); filterTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); filterTable.addStyleName(ValoTheme.TABLE_SMALL); filterTable.setSizeFull(); filterTable.setImmediate(true); filterTable.addActionHandler(this); filterTable.setCellStyleGenerator(new CustomTable.CellStyleGenerator() { @Override public String getStyle(CustomTable source, Object itemId, Object propertyId) { Flow flow = (Flow) itemId; String state = stateMap.get(flow.getModule().getName() + "-" + flow.getName()); if (propertyId == null) { // Styling for row if (state != null && state.equals(RUNNING)) { return "ikasan-green-small"; } else if (state != null && state.equals(RECOVERING)) { return "ikasan-orange-small"; } else if (state != null && state.equals(STOPPED)) { return "ikasan-red-small"; } else if (state != null && state.equals(STOPPED_IN_ERROR)) { return "ikasan-red-small"; } else if (state != null && state.equals(PAUSED)) { return "ikasan-indigo-small"; } } if (state != null && state.equals(RUNNING)) { return "ikasan-green-small"; } else if (state != null && state.equals(RECOVERING)) { return "ikasan-orange-small"; } else if (state != null && state.equals(STOPPED)) { return "ikasan-red-small"; } else if (state != null && state.equals(STOPPED_IN_ERROR)) { return "ikasan-red-small"; } else if (state != null && state.equals(PAUSED)) { return "ikasan-indigo-small"; } return "ikasan-small"; } }); return filterTable; } protected Container buildContainer() { cont = new IndexedContainer(); cont.addContainerProperty("Module Name", String.class, null); cont.addContainerProperty("Flow Name", String.class, null); cont.addContainerProperty("Flow State", String.class, null); return cont; } protected void toggleMaximized(final Component panel, final boolean maximized) { if (maximized) { panel.setVisible(true); panel.addStyleName("max"); } else { panel.removeStyleName("max"); } } public void populate(HashMap<String, String> stateMap) { for (Module module : server.getModules()) { for (Flow flow : module.getFlows()) { String state = stateMap.get(flow.getModule().getName() + "-" + flow.getName()); if (state == null) { state = "unknown"; } Item item = this.cont.getItem(flow); if (item != null && !item.getItemProperty("Flow State").getValue().equals(state)) { item.getItemProperty("Flow State").setValue(state); } else { item = this.cont.addItem(flow); if (item != null && flow != null) { item.getItemProperty("Module Name").setValue(flow.getModule().getName()); item.getItemProperty("Flow Name").setValue(flow.getName()); item.getItemProperty("Flow State").setValue(state); } } } } } @Subscribe public void receiveFlowStateEvent(final FlowStateEvent event) { UI.getCurrent().access(new Runnable() { @Override public void run() { VaadinSession.getCurrent().getLockInstance().lock(); try { stateMap = event.getFlowStateMap(); setStatusLabel(); populate(event.getFlowStateMap()); } finally { VaadinSession.getCurrent().getLockInstance().unlock(); } UI.getCurrent().push(); } }); } /* (non-Javadoc) * @see com.vaadin.event.Action.Handler#getActions(java.lang.Object, java.lang.Object) */ @Override public Action[] getActions(Object target, Object sender) { logger.info("Getting action: " + target + " " + sender); if (target instanceof Flow) { Flow flow = ((Flow) target); String state = this.stateMap.get(flow.getModule().getName() + "-" + flow.getName()); if (state != null && state.equals(RUNNING)) { return this.flowActionsStarted; } else if (state != null && (state.equals(RUNNING) || state.equals(RECOVERING))) { return this.flowActionsStarted; } else if (state != null && (state.equals(STOPPED) || state.equals(STOPPED_IN_ERROR))) { return this.flowActionsStopped; } else if (state != null && state.equals(PAUSED)) { return this.flowActionsPaused; } } return actionsEmpty; } /* (non-Javadoc) * @see com.vaadin.event.Action.Handler#handleAction(com.vaadin.event.Action, java.lang.Object, java.lang.Object) */ @Override public void handleAction(Action action, Object sender, Object target) { if (target != null && target instanceof Flow) { Flow flow = ((Flow) target); if (action.equals(START)) { this.actionFlow(flow, "start"); } else if (action.equals(STOP)) { this.actionFlow(flow, "stop"); } else if (action.equals(PAUSE)) { this.actionFlow(flow, "pause"); } else if (action.equals(RESUME)) { this.actionFlow(flow, "resume"); } else if (action.equals(START_PAUSE)) { this.actionFlow(flow, "startPause"); } } } protected boolean actionFlow(Flow flow, String action) { IkasanAuthentication authentication = (IkasanAuthentication) VaadinService.getCurrentRequest() .getWrappedSession().getAttribute(DashboardSessionValueConstants.USER); HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic(authentication.getName(), (String) authentication.getCredentials()); ClientConfig clientConfig = new ClientConfig(); clientConfig.register(feature); Client client = ClientBuilder.newClient(clientConfig); String url = "http://" + flow.getModule().getServer().getUrl() + ":" + flow.getModule().getServer().getPort() + flow.getModule().getContextRoot() + "/rest/moduleControl/controlFlowState/" + flow.getModule().getName() + "/" + flow.getName(); WebTarget webTarget = client.target(url); Response response = webTarget.request().put(Entity.entity(action, MediaType.APPLICATION_OCTET_STREAM)); if (response.getStatus() == 200) { Notification.show(flow.getName() + " flow " + action + "!"); } else { response.bufferEntity(); String responseMessage = response.readEntity(String.class); Notification.show(responseMessage, Type.ERROR_MESSAGE); return false; } return true; } /* (non-Javadoc) * @see com.vaadin.navigator.View#enter(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent) */ @Override public void enter(ViewChangeEvent event) { TopologyStateCache cache = (TopologyStateCache) VaadinSession.getCurrent() .getAttribute(DashboardSessionValueConstants.TOPOLOGY_STATE_CACHE); stateMap = cache.getStateMap(); setStatusLabel(); populate(stateMap); } }