Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

SWITCHYARD-1557 add support for service throttling

  • Loading branch information...
commit 0d297f8c817d730308f7b51c4b53d46d3c432c26 1 parent 8ee50ab
rcernich rcernich authored
6 gwt/src/main/java/org/switchyard/console/client/BeanFactory.java
View
@@ -31,6 +31,7 @@
import org.switchyard.console.client.model.Service;
import org.switchyard.console.client.model.ServiceMetrics;
import org.switchyard.console.client.model.SystemDetails;
+import org.switchyard.console.client.model.Throttling;
import org.switchyard.console.client.model.Transformer;
import org.switchyard.console.components.client.model.Component;
@@ -108,4 +109,9 @@
*/
AutoBean<ArtifactReference> artifactReference();
+ /**
+ * @return a new AutoBean<Throttling>
+ */
+ AutoBean<Throttling> throttling();
+
}
10 gwt/src/main/java/org/switchyard/console/client/model/Service.java
View
@@ -69,4 +69,14 @@
*/
public void setApplication(String application);
+ /**
+ * @return the throttling details for this service
+ */
+ public Throttling getThrottling();
+
+ /**
+ * @param throttling details for this service
+ */
+ public void setThrottling(Throttling throttling);
+
}
22 gwt/src/main/java/org/switchyard/console/client/model/SwitchYardStore.java
View
@@ -20,6 +20,7 @@
package org.switchyard.console.client.model;
import java.util.List;
+import java.util.Map;
import org.jboss.as.console.client.shared.properties.PropertyRecord;
import org.switchyard.console.client.BeanFactory;
@@ -193,4 +194,25 @@
*/
void stopGateway(String name, String serviceName, String applicationName, AsyncCallback<Void> callback);
+ /**
+ * Updates the throttling configuration for the specified service.
+ *
+ * @param service the service
+ * @param throttling the new throttling configuration
+ * @param callback the callback
+ */
+ void updateThrottling(Service service, Throttling throttling, AsyncCallback<Void> callback);
+
+ /**
+ * Create a new object from the change set.
+ *
+ * @param <T> the type of object
+ * @param type the type of object
+ * @param original the original object
+ * @param changeSet the changes
+ * @param merge true if the new object should include values merged from the
+ * original
+ * @return a new object
+ */
+ <T> T processChangeSet(Class<T> type, T original, Map<String, Object> changeSet, boolean merge);
}
71 gwt/src/main/java/org/switchyard/console/client/model/SwitchYardStoreImpl.java
View
@@ -37,13 +37,16 @@
import javax.inject.Inject;
-import org.jboss.as.console.client.core.ApplicationProperties;
import org.jboss.as.console.client.shared.dispatch.DispatchAsync;
import org.jboss.as.console.client.shared.dispatch.impl.DMRAction;
import org.jboss.as.console.client.shared.dispatch.impl.DMRResponse;
import org.jboss.as.console.client.shared.properties.PropertyRecord;
import org.jboss.as.console.client.shared.runtime.RuntimeBaseAddress;
import org.jboss.as.console.client.shared.subsys.Baseadress;
+import org.jboss.as.console.client.widgets.forms.ApplicationMetaData;
+import org.jboss.as.console.client.widgets.forms.EntityAdapter;
+import org.jboss.as.console.client.widgets.forms.Mutator;
+import org.jboss.as.console.client.widgets.forms.PropertyBinding;
import org.jboss.dmr.client.ModelNode;
import org.switchyard.console.client.BeanFactory;
import org.switchyard.console.client.NameTokens;
@@ -80,25 +83,25 @@
private static final String STOP_GATEWAY = "stop-gateway";
private static final String START_GATEWAY = "start-gateway";
private static final String SWITCHYARD = NameTokens.SUBSYSTEM;
+ private static final String THROTTLING = "throttling";
+ private static final String UPDATE_THROTTLING = "update-throttling";
private final DispatchAsync _dispatcher;
-
private final BeanFactory _factory;
-
- private final ApplicationProperties _bootstrap;
+ private final ApplicationMetaData _metadata;
/**
* Create a new SwitchYardStoreImpl.
*
* @param dispatcher the injected dispatcher.
* @param factory the injected bean factory.
- * @param bootstrap the injected bootstrap context.
+ * @param metadata the injected application metadata.
*/
@Inject
- public SwitchYardStoreImpl(DispatchAsync dispatcher, BeanFactory factory, ApplicationProperties bootstrap) {
+ public SwitchYardStoreImpl(DispatchAsync dispatcher, BeanFactory factory, ApplicationMetaData metadata) {
this._dispatcher = dispatcher;
this._factory = factory;
- this._bootstrap = bootstrap;
+ this._metadata = metadata;
}
@Override
@@ -776,6 +779,60 @@ public void onSuccess(DMRResponse result) {
});
}
+ @Override
+ public void updateThrottling(final Service service, final Throttling throttling, final AsyncCallback<Void> callback) {
+ // /subsystem=switchyard:update-throttling(service-name=name, application-name=applicationName, throttling=throttling)
+
+ final EntityAdapter<Throttling> entityAdapter = new EntityAdapter<Throttling>(Throttling.class, _metadata);
+ final ModelNode operation = new ModelNode();
+ final ModelNode address = RuntimeBaseAddress.get();
+ operation.get(OP).set(UPDATE_THROTTLING);
+ address.add(SUBSYSTEM, SWITCHYARD);
+ operation.get(OP_ADDR).set(address);
+ operation.get(SERVICE_NAME).set(service.getName());
+ operation.get(APPLICATION_NAME).set(service.getApplication());
+ operation.get(THROTTLING).set(entityAdapter.fromEntity(throttling));
+
+ _dispatcher.execute(new DMRAction(operation), new AsyncCallback<DMRResponse>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ callback.onFailure(caught);
+ }
+
+ @Override
+ public void onSuccess(DMRResponse result) {
+ final ModelNode response = result.get();
+ if (!response.hasDefined(FAILED)) {
+ callback.onSuccess(null);
+ return;
+ }
+ callback.onFailure(new Exception("Failure updating throttling details for " + service.localName() + ": "
+ + response.getFailureDescription()));
+ }
+ });
+ }
+
+ @Override
+ public <T> T processChangeSet(final Class<T> type, final T original, final Map<String, Object> changeSet,
+ final boolean merge) {
+ final List<PropertyBinding> properties = _metadata.getBeanMetaData(type).getProperties();
+ final T newEntity = (T) _metadata.getFactory(type).create();
+ @SuppressWarnings("unchecked")
+ final Mutator<T> mutator = _metadata.getMutator(type);
+
+ for (PropertyBinding property : properties) {
+ final String javaName = property.getJavaName();
+ Object propertyValue = mutator.getValue(original, javaName);
+ Object changed = changeSet.get(javaName);
+ if (changed != null && !changed.equals(propertyValue)) {
+ mutator.setValue(newEntity, javaName, changed);
+ } else if (merge) {
+ mutator.setValue(newEntity, javaName, propertyValue);
+ }
+ }
+ return newEntity;
+ }
+
private SystemDetails createSystemDetails(final ModelNode systemDetailsNode) {
try {
return AutoBeanCodex.decode(_factory, SystemDetails.class, systemDetailsNode.toJSONString(true)).as();
59 gwt/src/main/java/org/switchyard/console/client/model/Throttling.java
View
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package org.switchyard.console.client.model;
+
+/**
+ * Throttling
+ * <p/>
+ * Throttling details associated switchyard object.
+ */
+public interface Throttling {
+
+ /**
+ * @return true if throttling is enabled.
+ */
+ Boolean isEnabled();
+
+ /**
+ * @param enabled true to enable throttling.
+ */
+ void setEnabled(Boolean enabled);
+
+ /**
+ * @return the maximum number of requests per time period.
+ */
+ Integer getMaxRequests();
+
+ /**
+ * @param maxRequests the maximumn number of requests per time period.
+ */
+ void setMaxRequests(Integer maxRequests);
+
+ /**
+ * @return the time period, in milliseconds, over which requests are
+ * counted.
+ */
+ Long getTimePeriod();
+
+ /**
+ * @param timePeriod the time period, in milliseconds, over which requests
+ * are counted.
+ */
+ void setTimePeriod(Long timePeriod);
+}
147 gwt/src/main/java/org/switchyard/console/client/ui/service/ServiceEditor.java
View
@@ -19,17 +19,30 @@
package org.switchyard.console.client.ui.service;
+import java.util.Map;
+
+import org.jboss.as.console.client.widgets.ContentDescription;
+import org.jboss.as.console.client.widgets.forms.BlankItem;
+import org.jboss.as.console.client.widgets.forms.FormToolStrip;
import org.jboss.ballroom.client.widgets.ContentGroupLabel;
+import org.jboss.ballroom.client.widgets.forms.CheckBoxItem;
import org.jboss.ballroom.client.widgets.forms.Form;
+import org.jboss.ballroom.client.widgets.forms.FormItem;
+import org.jboss.ballroom.client.widgets.forms.FormValidation;
+import org.jboss.ballroom.client.widgets.forms.NumberBoxItem;
import org.jboss.ballroom.client.widgets.forms.TextItem;
import org.switchyard.console.client.NameTokens;
import org.switchyard.console.client.model.Service;
+import org.switchyard.console.client.model.Throttling;
import org.switchyard.console.client.ui.widgets.ClickableTextItem;
import org.switchyard.console.client.ui.widgets.ClickableTextItem.ValueAdapter;
import org.switchyard.console.client.ui.widgets.LocalNameFormItem;
import org.switchyard.console.client.ui.widgets.NamespaceFormItem;
+import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
+import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
@@ -46,7 +59,9 @@
private ServicePresenter _presenter;
private Form<Service> _implementationDetailsForm;
+ private Form<Throttling> _throttlingDetailsForm;
private GatewaysList _gatewaysList;
+ private FormToolStrip<Throttling> _toolstrip;
private Service _service;
@@ -69,13 +84,27 @@ public void setPresenter(ServicePresenter presenter) {
* @return this editor as a Widget.
*/
public Widget asWidget() {
- VerticalPanel layout = new VerticalPanel();
- layout.setStyleName("fill-layout-width");
+ VerticalPanel panel = new VerticalPanel();
+ panel.add(new ContentGroupLabel("Service Details"));
+ panel.add(new ContentDescription("Displays details for the selected service."));
+ panel.add(createImplementationDetailsPanel());
- layout.add(createImplementationDetailsPanel());
- layout.add(createGatewayDetailsPanel());
+ TabPanel tabs = new TabPanel();
+ tabs.setStyleName("default-tabpanel");
+ tabs.getElement().setAttribute("style", "margin-top:15px;");
+ tabs.add(createGatewayDetailsPanel(), "Gateways");
+ tabs.add(createThrottlingDetailsPanel(), "Throttling");
+ tabs.addBeforeSelectionHandler(new BeforeSelectionHandler<Integer>() {
+ @Override
+ public void onBeforeSelection(BeforeSelectionEvent<Integer> event) {
+ _toolstrip.doCancel();
+ }
+ });
- return layout;
+ panel.add(tabs);
+ tabs.selectTab(0);
+
+ return panel;
}
/**
@@ -84,14 +113,25 @@ public Widget asWidget() {
public void setService(Service service) {
_service = service;
- if (service.getInterface() == null) {
- // XXX: workaround to ensure interface field in the form gets set.
- service.setInterface("");
- }
+ _toolstrip.doCancel();
_implementationDetailsForm.clearValues();
- _implementationDetailsForm.edit(service);
- _gatewaysList.setData(service.getGateways());
+ _throttlingDetailsForm.clearValues();
+
+ if (service == null) {
+ _gatewaysList.setData(null);
+ } else {
+ if (service.getInterface() == null) {
+ // XXX: workaround to ensure interface field in the form gets
+ // set.
+ service.setInterface("");
+ }
+ _implementationDetailsForm.edit(service);
+ if (service.getThrottling() != null) {
+ _throttlingDetailsForm.edit(service.getThrottling());
+ }
+ _gatewaysList.setData(service.getGateways());
+ }
}
private Widget createImplementationDetailsPanel() {
@@ -138,13 +178,13 @@ public String getTargetHistoryToken(String value) {
_implementationDetailsForm.setNumColumns(2);
_implementationDetailsForm.setFields(nameItem, applicationItem, namespaceItem);
_implementationDetailsForm.setFieldsInGroup("Implementation Details", implementationItem, interfaceItem);
+ // don't disable as the fields won't display correctly
+ // _implementationDetailsForm.setEnabled(false);
- VerticalPanel implementationDetailsLayout = new VerticalPanel();
- implementationDetailsLayout.setStyleName("fill-layout-width");
- implementationDetailsLayout.add(new ContentGroupLabel("Service Details"));
- implementationDetailsLayout.add(_implementationDetailsForm.asWidget());
-
- return implementationDetailsLayout;
+ VerticalPanel layout = new VerticalPanel();
+ layout.setStyleName("fill-layout-width");
+ layout.add(_implementationDetailsForm.asWidget());
+ return layout;
}
private String createApplicationLink(String applicationName) {
@@ -160,4 +200,77 @@ private Widget createGatewayDetailsPanel() {
return _gatewaysList.asWidget();
}
+ private Widget createThrottlingDetailsPanel() {
+ VerticalPanel layout = new VerticalPanel();
+ layout.setStyleName("fill-layout-width");
+
+ CheckBoxItem enabledItem = new CheckBoxItem("enabled", "Enabled");
+ NumberBoxItem maxRequestsItem = new NumberBoxItem("maxRequests", "Maximum Requests") {
+ @Override
+ public boolean validate(Number value) {
+ return super.validate(value) && value.intValue() > 0;
+ }
+ };
+ NumberBoxItem timePeriodItem = new NumberBoxItem("timePeriod", "Time Period (millis)") {
+ @Override
+ public boolean validate(Number value) {
+ return super.validate(value) && value.intValue() > 0;
+ }
+ };
+ timePeriodItem.setEnabled(false);
+
+ _throttlingDetailsForm = new Form<Throttling>(Throttling.class) {
+ @SuppressWarnings("rawtypes")
+ public FormValidation validate() {
+ // copied from parent, but we always validate
+ FormValidation outcome = new FormValidation();
+ for (Map<String, FormItem> groupItems : formItems.values()) {
+ for (FormItem item : groupItems.values()) {
+ Object value = item.getValue();
+ // ascii or empty string are ok. the later will be
+ // checked in each form item implementation.
+ String stringValue = String.valueOf(value);
+ boolean ascii = stringValue.isEmpty() || stringValue.matches("^[\\u0020-\\u007e]+$");
+ if (!ascii) {
+ outcome.addError(item.getName());
+ item.setErroneous(true);
+ } else {
+ @SuppressWarnings("unchecked")
+ boolean validValue = item.validate(value);
+ if (validValue) {
+ item.setErroneous(false);
+ } else {
+ outcome.addError(item.getName());
+ item.setErroneous(true);
+ }
+ }
+ }
+ }
+ return outcome;
+ }
+ };
+ _throttlingDetailsForm.setNumColumns(2);
+ _throttlingDetailsForm.setFields(enabledItem, new BlankItem(), maxRequestsItem, timePeriodItem);
+ _throttlingDetailsForm.setEnabled(false);
+
+ // toolstrip
+ _toolstrip = new FormToolStrip<Throttling>(_throttlingDetailsForm,
+ new FormToolStrip.FormCallback<Throttling>() {
+ @Override
+ public void onSave(Map<String, Object> changeset) {
+ _presenter.updateThrottling(_service, _throttlingDetailsForm.getEditedEntity(), changeset);
+ }
+
+ @Override
+ public void onDelete(Throttling entity) {
+ }
+ });
+
+ _toolstrip.providesDeleteOp(false); // belongs to the top
+
+ layout.add(_toolstrip.asWidget());
+ layout.add(_throttlingDetailsForm.asWidget());
+
+ return layout;
+ }
}
27 gwt/src/main/java/org/switchyard/console/client/ui/service/ServicePresenter.java
View
@@ -20,6 +20,7 @@
package org.switchyard.console.client.ui.service;
import java.util.List;
+import java.util.Map;
import org.jboss.as.console.client.Console;
import org.jboss.ballroom.client.layout.LHSHighlightEvent;
@@ -27,6 +28,7 @@
import org.switchyard.console.client.model.Binding;
import org.switchyard.console.client.model.Service;
import org.switchyard.console.client.model.SwitchYardStore;
+import org.switchyard.console.client.model.Throttling;
import org.switchyard.console.client.ui.runtime.RuntimePresenter;
import com.google.gwt.core.client.Scheduler;
@@ -142,6 +144,29 @@ public void onFailure(Throwable caught) {
}
/**
+ * Updates the throttling configuration for the specified service.
+ *
+ * @param service the service
+ * @param throttling the new throttling configuration
+ * @param changeset what changed from the original configuration
+ */
+ public void updateThrottling(Service service, Throttling throttling, Map<String, Object> changeset) {
+ _switchYardStore.updateThrottling(service,
+ _switchYardStore.processChangeSet(Throttling.class, throttling, changeset, false),
+ new AsyncCallback<Void>() {
+ @Override
+ public void onSuccess(Void dummy) {
+ getEventBus().fireEvent(new ResetPresentersEvent());
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ Console.error("Unknown error", caught.getMessage());
+ }
+ });
+ }
+
+ /**
* Notifies the presenter that the user has selected a service. The
* presenter will load the service details and pass them back to the view to
* be displayed.
@@ -220,7 +245,7 @@ public void onFailure(Throwable caught) {
private void loadService() {
if (_serviceName == null || _applicationName == null) {
- getView().setService(_switchYardStore.getBeanFactory().service().as());
+ getView().setService(null);
return;
}
_switchYardStore.loadService(_serviceName, _applicationName, new AsyncCallback<Service>() {
Please sign in to comment.
Something went wrong with that request. Please try again.