Package org.fusesource.ide.jmx.camel.navigator

Source Code of org.fusesource.ide.jmx.camel.navigator.CamelContextNode

/*******************************************************************************
* Copyright (c) 2013 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Red Hat, Inc. - initial API and implementation
******************************************************************************/

package org.fusesource.ide.jmx.camel.navigator;

import io.fabric8.camel.facade.CamelFacade;
import io.fabric8.camel.facade.mbean.CamelContextMBean;
import io.fabric8.camel.facade.mbean.CamelFabricTracerMBean;
import io.fabric8.camel.facade.mbean.CamelProcessorMBean;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.camel.RuntimeCamelException;
import org.apache.camel.api.management.mbean.BacklogTracerEventMessage;
import org.apache.camel.api.management.mbean.ManagedBacklogTracerMBean;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.fusesource.ide.camel.model.AbstractNode;
import org.fusesource.ide.camel.model.AbstractNodeFacade;
import org.fusesource.ide.camel.model.Activator;
import org.fusesource.ide.camel.model.RouteContainer;
import org.fusesource.ide.camel.model.io.XmlContainerMarshaller;
import org.fusesource.ide.commons.tree.NodeSupport;
import org.fusesource.ide.commons.tree.Refreshable;
import org.fusesource.ide.commons.ui.ContextMenuProvider;
import org.fusesource.ide.commons.ui.Workbenches;
import org.fusesource.ide.commons.util.Function1;
import org.fusesource.ide.commons.util.Nodes;
import org.fusesource.ide.commons.util.Objects;
import org.fusesource.ide.jmx.camel.CamelJMXPlugin;
import org.fusesource.ide.jmx.camel.Messages;
import org.fusesource.ide.jmx.camel.editor.CamelContextNodeEditorInput;
import org.fusesource.ide.jmx.commons.messages.IExchange;
import org.fusesource.ide.jmx.commons.messages.IMessage;
import org.fusesource.ide.jmx.commons.messages.ITraceExchangeBrowser;
import org.fusesource.ide.jmx.commons.messages.ITraceExchangeList;
import org.fusesource.ide.jmx.commons.messages.NodeStatisticsContainer;
import org.jboss.tools.jmx.ui.ImageProvider;


public class CamelContextNode extends NodeSupport implements Refreshable, AbstractNodeFacade, ContextMenuProvider, ITraceExchangeBrowser,
ImageProvider {

  public static final String CAMEL_EDITOR_ID = "org.fusesource.ide.camel.editor";
  private final CamelContextsNode camelContextsNode;
  private final CamelFacade facade;
  private final CamelContextMBean camelContextMBean;
  private XmlContainerMarshaller marshaller = new XmlContainerMarshaller();
  private final RoutesNode routes;
  private Map<String, TraceExchangeList> traceMessageMap = new ConcurrentHashMap<String, TraceExchangeList>();
  private NodeStatisticsContainer runtimeNodeStatisticsContainer;

  public CamelContextNode(CamelContextsNode camelContextsNode, CamelFacade facade, CamelContextMBean camelContext) throws Exception {
    super(camelContextsNode);
    this.camelContextsNode = camelContextsNode;
    this.facade = facade;
    this.camelContextMBean = camelContext;

    routes = new RoutesNode(this);
    addChild(routes);
    addChild(new EndpointsNode(this));
    setPropertyBean(camelContext);
  }

  @Override
  public String toString() {
    return getContextId();
  }

  @Override
  public void refresh() {
    Nodes.refreshParent(this);
  }

  public CamelContextsNode getCamelContextsNode() {
    return camelContextsNode;
  }

  public String getContextId() {
    try {
      return camelContextMBean.getCamelId();
    } catch (Exception e) {
      return "";
    }
  }

  public String getManagementName() {
    try {
      return camelContextMBean.getManagementName();
    } catch (Exception e) {
      return "";
    }
  }

  public CamelFacade getFacade() {
    return facade;
  }

  public CamelContextMBean getCamelContextMBean() {
    return camelContextMBean;
  }

  public String getXmlString() {
    try {
      return camelContextMBean.dumpRoutesAsXml();
    } catch (Exception e) {
      return "";
    }
  }

  public RouteContainer getModelContainer() {
    String xml = getXmlText();
    return marshaller.loadRoutesFromText(xml);
  }

  public String getXmlText() {
    String xml = getXmlString();
    // TODO - REMOVE ASAP
    // lets add in the camel context...
    if (!xml.contains("<camelContext")) {
      String routeElement = "<routes";
      if (xml.contains(routeElement)) {
        xml = xml.replace(routeElement, "<camelContext").replace("</routes>", "</camelContext>");
      }
    }
    return xml;
  }

  public void updateXml(String xml) {
    camelContextMBean.addOrUpdateRoutesFromXml(xml);
    refresh();
  }

  @Override
  public AbstractNode getAbstractNode() {
    return getRoutes().getAbstractNode();
  }

  public XmlContainerMarshaller getMarshaller() {
    return marshaller;
  }

  public void setMarshaller(XmlContainerMarshaller marshaller) {
    this.marshaller = marshaller;
  }

  public RoutesNode getRoutes() {
    return routes;
  }

  public boolean isTracing() {
    Object tracer = getTracer();
    if (tracer == null) return false;
   
    if (tracer instanceof ManagedBacklogTracerMBean) {
      return ((ManagedBacklogTracerMBean)tracer).isEnabled();
    } else {
      return ((CamelFabricTracerMBean)tracer).isEnabled();
    }
  }

  // Operations

  /**
   * Sends a message to the given URI
   */
  public void send(String endpointUri, IMessage message) {
    Object body = message.getBody();
    Map<String, Object> headers = message.getHeaders();
    getCamelContextMBean().sendBodyAndHeaders(endpointUri, body, headers);

    reloadRoutes();
  }

  public void startTracing() {
    try {
      Object tracer = getTracer();
      if (tracer instanceof ManagedBacklogTracerMBean) {
        ((ManagedBacklogTracerMBean)tracer).setEnabled(true);
      } else {
        ((CamelFabricTracerMBean)tracer).setEnabled(true);
      }
      reloadRoutes();
      refresh();
    } catch (Exception e) {
      CamelJMXPlugin.showUserError("Failed to start tracing", "Failed to start tracing context " + this, e);
    }
  }

  protected void reloadRoutes() {
    // we now need to force a reload of the Camel routes models; so that they include any generated IDs...
    routes.refresh();
  }

  public void stopTracing() {
    Object tracer = getTracer();
    if (tracer instanceof ManagedBacklogTracerMBean) {
      ((ManagedBacklogTracerMBean)tracer).setEnabled(false);
    } else {
      ((CamelFabricTracerMBean)tracer).setEnabled(false);
    }
    traceMessageMap.clear();
    reloadRoutes();
    refresh();
  }

  public void editRoutes() {
    IWorkbenchPage page = Workbenches.getActiveWorkbenchPage();
    if (page == null) {
      Activator.getLogger().warning("No active page!");
    } else {
      IEditorInput input = new CamelContextNodeEditorInput(this);
      try {
        page.openEditor(input, CAMEL_EDITOR_ID, true);
      } catch (PartInitException e) {
        Activator.getLogger().warning("Could not open editor: " + CAMEL_EDITOR_ID + ". Reason: " + e, e);
      }
      /*
      IViewPart view = page.findView(CAMEL_EDITOR_ID);
      if (view == null) {
        try {
          view = page.showView(CAMEL_EDITOR_ID);
        } catch (PartInitException e) {
          Activator.getLogger().warning("Could not find editor: " + CAMEL_EDITOR_ID);
        }
      }
      if (view != null) {
        if (view instanceof IEditorPart) {
          IEditorPart editor = (IEditorPart) view;
          IEditorInput input = new CamelContextNodeEditorInput(this);
          IEditorSite site = null;
          try {
            editor.init(site , input);
            editor.setFocus();
          } catch (PartInitException e) {
            Activator.getLogger().warning("Could not initialise editor: " + view);
          }
        } else {
          Activator.getLogger().warning("View is not an IEditorPart: " + view);
        }
      }
       */
    }


  }

  @Override
  public void provideContextMenu(IMenuManager menu) {
    provideContextMenu(menu, null);

  }

  public void provideContextMenu(IMenuManager menu, Function1<IMenuManager, Void> fn) {
    Action editAction = new Action(Messages.EditRoutesAction, SWT.CHECK) {
      @Override
      public void run() {
        editRoutes();
      }
      /* (non-Javadoc)
       * @see org.eclipse.jface.action.Action#isEnabled()
       */
      @Override
      public boolean isEnabled() {
        return routes.getChildCount()>0;
      }
    };
    editAction.setToolTipText(Messages.EditRoutesActionToolTip);
    editAction.setImageDescriptor(CamelJMXPlugin.getDefault().getImageDescriptor("edit_camel_route.png"));
    menu.add(editAction);

    if (fn != null) {
      fn.apply(menu);
    } else {
      if (isMbeanSuspended()) {
        Action resumeContextAction = new Action(Messages.ResumeCamelContextAction, SWT.CHECK) {
          @Override
          public void run() {
            resumeMBean();
          }
        };
        resumeContextAction.setToolTipText(Messages.ResumeCamelContextActionToolTip);
        resumeContextAction.setImageDescriptor(CamelJMXPlugin.getDefault().getImageDescriptor("start_camel.png"));
        menu.add(resumeContextAction);
      } else {
        Action suspendContextAction = new Action(Messages.SuspendCamelContextAction, SWT.CHECK) {
          @Override
          public void run() {
            suspendMBean();
          }
        };
        suspendContextAction.setToolTipText(Messages.SuspendCamelContextActionToolTip);
        suspendContextAction.setImageDescriptor(CamelJMXPlugin.getDefault().getImageDescriptor("pause_camel.png"));
        menu.add(suspendContextAction);
      }
//      Action stopContextAction = new Action(Messages.StopCamelContextAction, SWT.CHECK) {
//        @Override
//        public void run() {
//          stopMBean();
//        }
//      };
//      stopContextAction.setToolTipText(Messages.StopCamelContextActionToolTip);
//      stopContextAction.setImageDescriptor(FabricPlugin.getDefault().getImageDescriptor("stop_camel.png"));
//      menu.add(stopContextAction);
    }

    if (canTrace()) {
      menu.add(new Separator());
      boolean tracing = isTracing();
      Action traceAction;
      if (tracing) {
        traceAction = new Action(Messages.StopTraceAction, SWT.CHECK) {
          @Override
          public void run() {
            stopTracing();
          }
          /* (non-Javadoc)
           * @see org.eclipse.jface.action.Action#isEnabled()
           */
          @Override
          public boolean isEnabled() {
            return routes.getChildCount()>0;
          }
        };
        traceAction.setToolTipText(Messages.StopTraceActionToolTip);
        traceAction.setImageDescriptor(CamelJMXPlugin.getDefault().getImageDescriptor("stop_tracing.png"));
      } else {
        traceAction = new Action(Messages.TraceAction, SWT.CHECK) {
          @Override
          public void run() {
            startTracing();
          }
          /* (non-Javadoc)
           * @see org.eclipse.jface.action.Action#isEnabled()
           */
          @Override
          public boolean isEnabled() {
            return routes.getChildCount()>0;
          }
        };
        traceAction.setToolTipText(Messages.TraceActionToolTip);
        traceAction.setImageDescriptor(CamelJMXPlugin.getDefault().getImageDescriptor("start_tracing.png"));
      }
      menu.add(traceAction);
    }
  }

  /**
   * Returns true if the camel version allows tracing
   */
  protected boolean canTrace() {
    return getTracer() != null;
  }

  protected void startMBean() {
    camelContextMBean.start();
    refresh();
  }

  protected void stopMBean() {
    camelContextMBean.stop();
    camelContextsNode.removeChild(this);
  }

  protected void suspendMBean() {
    camelContextMBean.suspend();
    refresh();
  }

  protected void resumeMBean() {
    camelContextMBean.resume();
    refresh();
  }


  public boolean isMbeanSuspended() {
    String state = camelContextMBean.getState();
    return Objects.equal("Suspended", state);
  }

  @Override
  public List<IExchange> browseExchanges() {
    // String nodeId = getContextId();
    // TODO remove when we can browse by context ID
    String nodeId = null;
    return getTraceExchanges(nodeId);
  }

  @Override
  public NodeStatisticsContainer getNodeStatisticsContainer() {
    //    if (isTracing()) {
    //      return getTraceExchangeList(null);
    //    } else {
    if (runtimeNodeStatisticsContainer == null) {
      runtimeNodeStatisticsContainer = new CachingCamelContextNodeStatisticsContainer(this);
    }
    return runtimeNodeStatisticsContainer;
    //    }
  }

  public NodeStatisticsContainer getNodeStatisticsContainer(String routeId) {
    //    if (isTracing()) {
    //      return getTraceExchangeList(routeId);
    //    } else {
    return getNodeStatisticsContainer();
    //    }
  }

  public ITraceExchangeList getTraceExchangeList(String id) {
    if (id != null) {
      // TODO lets find all the messages and filter them...
      return getTraceExchangeList(null);
    }
    TraceExchangeList traceList = null;
    String key = id;
    if (key == null) {
      key = getContextId();
    }
    traceList = traceMessageMap.get(key);
    if (traceList == null) {
      traceList = new TraceExchangeList();
      traceMessageMap.put(key, traceList);
    }
    try {
      // TODO we should add trace messages for a specific route ID to the
      // all routes
      Object tracer = getTracer();
      if (tracer instanceof ManagedBacklogTracerMBean) {
        ManagedBacklogTracerMBean camelTracer = (ManagedBacklogTracerMBean)tracer;
        if (camelTracer != null) {
          List<BacklogTracerEventMessage> traceMessages = null;
          if (id == null) {
            traceMessages = camelTracer.dumpAllTracedMessages();
          } else {
            traceMessages = camelTracer.dumpTracedMessages(id);
          }
          traceList.addBackLogTraceMessages(traceMessages);
        } else {
          // TODO should we highlight in the UI that there's no tracer enabled?
        }
      } else {
        CamelFabricTracerMBean fabricTracer = (CamelFabricTracerMBean)tracer;
        if (fabricTracer != null) {
          String traceXml = fabricTracer.dumpAllTracedMessagesAsXml();
          List<BacklogTracerEventMessage> traceMessages;
          if (id == null) {
            traceMessages = getTraceMessagesFromXml(traceXml);
          } else {
            traceMessages = getTraceMessagesFromXml(traceXml, id);
          }
          traceList.addFabricTraceMessages(traceMessages);
        } else {
          // TODO should we highlight in the UI that there's no tracer enabled?
        }
      }     
    } catch (Exception e) {
      CamelJMXPlugin.showUserError("Failed to get tracing messages",
          "Failed to get tracing messages on CamelContext " + this, e);
    }
    return traceList;
  }
 
  private List<BacklogTracerEventMessage> getTraceMessagesFromXml(String xmlDump) {
    List<BacklogTracerEventMessage> events = new ArrayList<BacklogTracerEventMessage>();
   
    // TODO: unmarshal events from the xml and put to the list of messages
    System.err.println("TODO: CamelContextNode.getTraceMessagesFromXml()");
 
    System.out.println(xmlDump);
   
    return events;
  }

  private List<BacklogTracerEventMessage> getTraceMessagesFromXml(String xmlDump, String id) {
    List<BacklogTracerEventMessage> events = new ArrayList<BacklogTracerEventMessage>();
   
    // TODO: unmarshal events from the xml and put to the list of messages
    System.err.println("TODO: CamelContextNode.getTraceMessagesFromXml(id)");
   
    System.out.println(id + ": >>> \n" + xmlDump);
   
    return events;
  }
 
  @Override
  public Image getImage() {
    if (isTracing()) {
      return CamelJMXPlugin.getDefault().getImage("camel_tracing.png");
    } else {
      return CamelJMXPlugin.getDefault().getImage("camel.png");
    }
  }

  public List<IExchange> getTraceExchanges(String id) {
    return getTraceExchangeList(id).getExchangeList();
  }

  public Object getTracer() {
    try {
      ManagedBacklogTracerMBean mbean = getFacade().getCamelTracer(getManagementName());
      if (mbean != null) {
        return mbean;
      } else {
        return getFacade().getFabricTracer(getManagementName());
      }
    } catch (Exception e) {
      throw new RuntimeCamelException(e);
    }
  }

  public CamelProcessorMBean getProcessorMBean(String nodeId) {
    return CamelFacades.getProcessorMBean(getFacade(), getManagementName(), nodeId);
  }

  public Object createProcessorBeanView(String routeId, String nodeId) {
    return new ProcessorBeanView(this, routeId, nodeId);
  }

}
TOP

Related Classes of org.fusesource.ide.jmx.camel.navigator.CamelContextNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.