Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SWITCHYARD-1694 rework message metrics calculations #584

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions admin/src/main/java/org/switchyard/admin/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ public interface Application {
*/
public ComponentService getComponentService(QName componentServiceName);

/**
* List of implementation and gateway components currently installed in
* SwitchYard runtime.
*
* @return list of SwitchYard components
*/
public List<Component> getComponents();

/**
* Find a component with the specified name.
*
* @param name
* the name of the component.
* @return the component with the specified name; may be null if a component
* with the specified name is not registered with the system.
*/
public Component getComponent(QName name);

/**
* @return the transformers provided by this application
*/
Expand Down
30 changes: 24 additions & 6 deletions admin/src/main/java/org/switchyard/admin/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,47 @@

package org.switchyard.admin;

import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;

/**
* Component
*
* Represents a SwitchYard component registered with the SwitchYard runtime
* (e.g. camel).
* Represents a SwitchYard component within an application.
*/
public interface Component {
/**
* @return the name of this component.
*/
String getName();
QName getName();

/**
* @return supported activation types, e.g. bean, soap, etc.
* @return implementation type, e.g. bean, bpm, etc.
*/
Set<String> getTypes();
String getType();

/**
* @return component properties.
*/
Map<String,String> getProperties();


/**
* @return the service provided by this component.
*/
ComponentService getService();

/**
* @return the references contained by this component.
*/
List<ComponentReference> getReferences();

/**
* @param componentReferenceName the name of a reference required by
* this component.
* @return the requested reference, may be null
*/
ComponentReference getReference(QName componentReferenceName);
}
18 changes: 0 additions & 18 deletions admin/src/main/java/org/switchyard/admin/SwitchYard.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,6 @@ public interface SwitchYard extends MessageMetricsAware {
*/
List<Application> getApplications();

/**
* List of implementation and gateway components currently installed in
* SwitchYard runtime.
*
* @return list of SwitchYard components
*/
List<Component> getComponents();

/**
* List of services currently registered in the SwitchYard runtime.
*
Expand All @@ -61,16 +53,6 @@ public interface SwitchYard extends MessageMetricsAware {
*/
List<Reference> getReferences();

/**
* Find a component with the specified name.
*
* @param name
* the name of the component.
* @return the component with the specified name; may be null if a component
* with the specified name is not registered with the system.
*/
Component getComponent(String name);

/**
* Find an application with the specified name.
*
Expand Down
154 changes: 136 additions & 18 deletions admin/src/main/java/org/switchyard/admin/base/BaseApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,47 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.EventObject;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;

import org.switchyard.Exchange;
import org.switchyard.admin.Application;
import org.switchyard.admin.Component;
import org.switchyard.admin.ComponentReference;
import org.switchyard.admin.ComponentService;
import org.switchyard.admin.Reference;
import org.switchyard.admin.Service;
import org.switchyard.admin.Transformer;
import org.switchyard.admin.Validator;
import org.switchyard.config.model.composite.ComponentModel;
import org.switchyard.config.model.composite.ComponentReferenceModel;
import org.switchyard.config.model.composite.ComponentServiceModel;
import org.switchyard.config.model.composite.CompositeReferenceModel;
import org.switchyard.config.model.composite.CompositeServiceModel;
import org.switchyard.config.model.composite.InterfaceModel;
import org.switchyard.config.model.property.PropertyModel;
import org.switchyard.config.model.switchyard.EsbInterfaceModel;
import org.switchyard.config.model.switchyard.SwitchYardModel;
import org.switchyard.config.model.transform.TransformModel;
import org.switchyard.config.model.validate.ValidateModel;
import org.switchyard.deploy.ComponentNames;
import org.switchyard.deploy.internal.AbstractDeployment;
import org.switchyard.event.EventObserver;
import org.switchyard.runtime.event.ExchangeCompletionEvent;

/**
* Base implementation of Application.
*/
public class BaseApplication implements Application {
public class BaseApplication implements Application, EventObserver {

private final QName _name;
private Map<QName, Service> _services;
private Map<QName, Reference> _references;
private Map<QName, Component> _components;
private Map<QName, ComponentService> _componentServices;
private List<Transformer> _transformers;
private List<Validator> _validators;
Expand All @@ -69,6 +77,14 @@ public BaseApplication(AbstractDeployment deployment) {
addServices();
addReferences();
addProperties();

// register event listener for metrics
_deployment.getDomain().addEventObserver(this, ExchangeCompletionEvent.class);
}

void dispose() {
// remove event listener for metrics
_deployment.getDomain().removeObserver(this);
}

@Override
Expand Down Expand Up @@ -129,6 +145,16 @@ public ComponentService getComponentService(QName componentServiceName) {
return _componentServices.get(componentServiceName);
}

@Override
public Component getComponent(QName name) {
return _components.get(name);
}

@Override
public List<Component> getComponents() {
return new ArrayList<Component>(_components.values());
}

@Override
public List<Transformer> getTransformers() {
return Collections.unmodifiableList(_transformers);
Expand All @@ -145,6 +171,13 @@ public Map<String, String> getProperties() {
return Collections.unmodifiableMap(_properties);
}

@Override
public void notify(EventObject event) {
if (event instanceof ExchangeCompletionEvent) {
exchangeCompleted((ExchangeCompletionEvent)event);
}
}

/**
* @return the deployment associated with this application.
*/
Expand Down Expand Up @@ -195,35 +228,120 @@ private void addValidators() {
}

private void addComponents() {
_components = new LinkedHashMap<QName, Component>();
_componentServices = new LinkedHashMap<QName, ComponentService>();
if (getConfig().getComposite().getComponents() == null) {
return;
}
for (ComponentModel component : getConfig().getComposite().getComponents()) {
// TODO: we need a separate node for components, to support cases
// where the component implements no services. Should also consider
// multiple services per component.
if (component.getServices().size() > 0) {
ComponentServiceModel service = component.getServices().get(0);
if (service.getInterface() == null || EsbInterfaceModel.ESB.equals(service.getInterface().getType())) {
_componentServices.put(service.getQName(), new BaseNoopComponentService(service, component, this));
} else if (InterfaceModel.JAVA.equals(service.getInterface().getType())) {
_componentServices.put(service.getQName(), new BaseJavaComponentService(service, component, this));
} else if (InterfaceModel.WSDL.equals(service.getInterface().getType())) {
_componentServices.put(service.getQName(), new BaseWsdlComponentService(service, component, this));
for (ComponentModel componentConfig : getConfig().getComposite().getComponents()) {
// TODO: Should consider multiple services per component.
final ComponentService service;
if (componentConfig.getServices().size() > 0) {
ComponentServiceModel serviceConfig = componentConfig.getServices().get(0);
if (serviceConfig.getInterface() == null) {
service = new BaseNoopComponentService(serviceConfig, componentConfig, this);
} else if (InterfaceModel.JAVA.equals(serviceConfig.getInterface().getType())) {
service = new BaseJavaComponentService(serviceConfig, componentConfig, this);
} else if (InterfaceModel.WSDL.equals(serviceConfig.getInterface().getType())) {
service = new BaseWsdlComponentService(serviceConfig, componentConfig, this);
} else {
// ESB or unknown
service = new BaseNoopComponentService(serviceConfig, componentConfig, this);
}
_componentServices.put(serviceConfig.getQName(), service);
} else {
service = null;
}
final Map<QName, ComponentReference> references = new LinkedHashMap<QName, ComponentReference>();
if (service == null) {
for (ComponentReferenceModel referenceModel : componentConfig.getReferences()) {
references.put(referenceModel.getQName(), new BaseComponentReference(referenceModel.getQName(),
getInterfaceName(referenceModel.getInterface())));
}
} else {
for (ComponentReference reference : service.getReferences()) {
references.put(reference.getName(), reference);
}
}
final BaseComponent component = new BaseComponent(componentConfig.getQName(),
componentConfig.getImplementation() == null ? "null" : componentConfig.getImplementation()
.getType(), service, references, convertProperties(componentConfig.getProperties()));
_components.put(component.getName(), component);
}
}

private void addProperties() {
_properties = new LinkedHashMap<String, String>();
if (getConfig().getComposite() == null) {
return;
_properties = convertProperties(null);
} else {
_properties = convertProperties(getConfig().getComposite().getProperties());
}
}

private Map<String,String> convertProperties(final Map<String, PropertyModel> properties) {
final Map<String,String> retVal = new LinkedHashMap<String, String>();
if (properties == null) {
return retVal;
}
for (PropertyModel property : getConfig().getComposite().getProperties().values()) {
_properties.put(property.getName(), property.getValue());
for (PropertyModel property : properties.values()) {
retVal.put(property.getName(), property.getValue());
}
return retVal;
}

private String getInterfaceName(InterfaceModel interfaceModel) {
if (interfaceModel == null) {
return null;
}
return interfaceModel.getInterface();
}

void exchangeCompleted(final ExchangeCompletionEvent event) {
// Recording metrics at multiple levels at this point instead of
// aggregating them.
final Exchange exchange = event.getExchange();
final QName qualifiedReferenceName = exchange.getConsumer().getName();
final QName referenceName = ComponentNames.unqualify(qualifiedReferenceName);
final QName componentName = ComponentNames.comopnentName(qualifiedReferenceName);
if (componentName == null) {
// service gateway initiated exchange
final Service service = _services.get(referenceName);
if (service != null) {
/*
* service also records promoted component service metrics too
* (i.e. producer metrics)
*/
service.recordMetrics(exchange);
}
} else {
// component reference initiated exchange
// 1 - recored service metrics (producer)
final QName serviceName = exchange.getProvider().getName();
final ComponentService service = _componentServices.get(serviceName);
if (service == null) {
// must be routed to composite reference
final Reference reference = _references.get(serviceName);
if (reference != null) {
reference.recordMetrics(exchange);
}
} else {
/*
* XXX: this could throw off metrics for composite services
* since they simply return the metrics for the component
* service they promote. That said, the metrics for the gateways
* will correlate with the global metrics.
*/
service.recordMetrics(exchange);
}
// 2 - record reference metrics (consumer)
final Component component = _components.get(componentName);
if (component != null) {
final ComponentReference reference = component.getReference(referenceName);
if (reference != null) {
reference.recordMetrics(exchange);
}
// else may have been an internal invocation, e.g. orders demo
}
}
}
}
Loading