<module name="AvoidStarImport"/>\r
<module name="UpperEll"/>\r
<module name="EmptyStatement"/>\r
+ <module name="EqualsHashCode"/>\r
</module>\r
\r
</module>\r
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
<version>7.0.42</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<!-- yang model dependencies -->
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.config.threadpool.util;
+
+import java.io.Closeable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+
+/**
+ * Implementation of {@link ThreadPool} using fixed number of threads wraps
+ * {@link ExecutorService}.
+ */
+public class FixedThreadPoolWrapper implements ThreadPool, Closeable {
+
+ private final ThreadPoolExecutor executor;
+
+ public FixedThreadPoolWrapper(int threadCount, ThreadFactory factory) {
+ this.executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadCount, factory);
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public ExecutorService getExecutor() {
+ return Executors.unconfigurableExecutorService(executor);
+ }
+
+ @Override
+ public void close() {
+ executor.shutdown();
+ }
+
+ @Override
+ public int getMaxThreadCount() {
+ return executor.getMaximumPoolSize();
+ }
+
+ public void setMaxThreadCount(int maxThreadCount) {
+ executor.setCorePoolSize(maxThreadCount);
+ executor.setMaximumPoolSize(maxThreadCount);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.config.threadpool.util;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+
+/**
+ * Implementation of {@link ThreadPool} using flexible number of threads wraps
+ * {@link ExecutorService}.
+ */
+public class FlexibleThreadPoolWrapper implements ThreadPool, Closeable {
+ private final ThreadPoolExecutor executor;
+
+ public FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit,
+ ThreadFactory threadFactory) {
+
+ executor = new ThreadPoolExecutor(minThreadCount, maxThreadCount, keepAlive, timeUnit,
+ new SynchronousQueue<Runnable>(), threadFactory);
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public ExecutorService getExecutor() {
+ return Executors.unconfigurableExecutorService(executor);
+ }
+
+ public int getMinThreadCount() {
+ return executor.getCorePoolSize();
+ }
+
+ public void setMinThreadCount(int minThreadCount) {
+ executor.setCorePoolSize(minThreadCount);
+ }
+
+ @Override
+ public int getMaxThreadCount() {
+ return executor.getMaximumPoolSize();
+ }
+
+ public void setMaxThreadCount(int maxThreadCount) {
+ executor.setMaximumPoolSize(maxThreadCount);
+ }
+
+ public long getKeepAliveMillis() {
+ return executor.getKeepAliveTime(TimeUnit.MILLISECONDS);
+ }
+
+ public void setKeepAliveMillis(long keepAliveMillis) {
+ executor.setKeepAliveTime(keepAliveMillis, TimeUnit.MILLISECONDS);
+ }
+
+ public void setThreadFactory(ThreadFactory threadFactory) {
+ executor.setThreadFactory(threadFactory);
+ }
+
+ public void prestartAllCoreThreads() {
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public void close() throws IOException {
+ executor.shutdown();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.config.threadpool.util;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Implementation of {@link ThreadFactory}.
+ */
+@ThreadSafe
+public class NamingThreadPoolFactory implements ThreadFactory, Closeable {
+
+ private final ThreadGroup group;
+ private final String namePrefix;
+ private final AtomicLong threadName = new AtomicLong();
+
+ public NamingThreadPoolFactory(String namePrefix) {
+ Preconditions.checkNotNull(namePrefix);
+ this.group = new ThreadGroup(namePrefix);
+ this.namePrefix = namePrefix;
+ }
+
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(group, r, String.format("%s-%d", group.getName(), threadName.incrementAndGet()));
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ public String getNamePrefix() {
+ return namePrefix;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.config.threadpool.util;
+
+import java.io.Closeable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+
+/**
+ * Implementation of {@link ScheduledThreadPool} wraps
+ * {@link ScheduledExecutorService}.
+ */
+public class ScheduledThreadPoolWrapper implements ScheduledThreadPool, Closeable {
+
+ private final ScheduledThreadPoolExecutor executor;
+ private final int threadCount;
+
+ public ScheduledThreadPoolWrapper(int threadCount, ThreadFactory factory) {
+ this.threadCount = threadCount;
+ this.executor = new ScheduledThreadPoolExecutor(threadCount, factory);
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public ScheduledExecutorService getExecutor() {
+ return Executors.unconfigurableScheduledExecutorService(executor);
+ }
+
+ @Override
+ public void close() {
+ executor.shutdown();
+ }
+
+ @Override
+ public int getMaxThreadCount() {
+ return threadCount;
+ }
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-fixed
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.FixedThreadPoolWrapper;
+
+/**
+*
+*/
+public final class FixedThreadPoolModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFixedThreadPoolModule {
+
+ public FixedThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public FixedThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ FixedThreadPoolModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+
+ JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero",
+ maxThreadCountJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new FixedThreadPoolWrapper(getMaxThreadCount(), getThreadFactoryDependency());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-fixed
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class FixedThreadPoolModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFixedThreadPoolModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-flexible
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.FlexibleThreadPoolWrapper;
+
+/**
+*
+*/
+public final class FlexibleThreadPoolModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFlexibleThreadPoolModule {
+
+ public FlexibleThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public FlexibleThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ FlexibleThreadPoolModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ JmxAttributeValidationException.checkNotNull(getKeepAliveMillis(), keepAliveMillisJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getKeepAliveMillis() > 0, "must be greater than zero",
+ keepAliveMillisJmxAttribute);
+
+ JmxAttributeValidationException.checkNotNull(getMinThreadCount(), minThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMinThreadCount() > 0, "must be greater than zero",
+ minThreadCountJmxAttribute);
+
+ JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero",
+ maxThreadCountJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new FlexibleThreadPoolWrapper(getMinThreadCount(), getMaxThreadCount(), getKeepAliveMillis(),
+ TimeUnit.MILLISECONDS, getThreadFactoryDependency());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-flexible
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class FlexibleThreadPoolModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFlexibleThreadPoolModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadfactory-naming
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.NamingThreadPoolFactory;
+
+/**
+*
+*/
+public final class NamingThreadFactoryModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractNamingThreadFactoryModule {
+
+ public NamingThreadFactoryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public NamingThreadFactoryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ NamingThreadFactoryModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ JmxAttributeValidationException.checkNotNull(getNamePrefix(), namePrefixJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new NamingThreadPoolFactory(getNamePrefix());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadfactory-naming
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class NamingThreadFactoryModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractNamingThreadFactoryModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-scheduled
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.ScheduledThreadPoolWrapper;
+
+/**
+*
+*/
+public final class ScheduledThreadPoolModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractScheduledThreadPoolModule {
+
+ public ScheduledThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public ScheduledThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ ScheduledThreadPoolModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero",
+ maxThreadCountJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new ScheduledThreadPoolWrapper(getMaxThreadCount(), getThreadFactoryDependency());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-scheduled
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class ScheduledThreadPoolModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractScheduledThreadPoolModuleFactory {
+
+}
}
}
-
-
rpc get-dead-events-count {
config:java-name-prefix countDeadEvents;
input {
}
}
}
+
+ identity threadfactory-naming {
+ base config:module-type;
+ config:provided-service th:threadfactory;
+ config:java-name-prefix NamingThreadFactory;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadfactory-naming {
+ when "/config:modules/config:module/config:type = 'threadfactory-naming'";
+ leaf name-prefix {
+ type string;
+ }
+ }
+ }
+
+ identity threadpool-fixed {
+ base config:module-type;
+ config:provided-service th:threadpool;
+ config:java-name-prefix FixedThreadPool;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadpool-fixed {
+ when "/config:modules/config:module/config:type = 'threadpool-fixed'";
+ leaf max-thread-count {
+ type uint16;
+ }
+
+ container threadFactory {
+ uses config:service-ref {
+ refine type {
+ //mandatory true;
+ config:required-identity th:threadfactory;
+ }
+ }
+ }
+ }
+ }
+
+ identity threadpool-flexible {
+ base config:module-type;
+ config:provided-service th:threadpool;
+ config:java-name-prefix FlexibleThreadPool;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadpool-flexible {
+ when "/config:modules/config:module/config:type = 'threadpool-flexible'";
+ leaf max-thread-count {
+ type uint16;
+ }
+ leaf minThreadCount {
+ type uint16;
+ }
+ leaf keepAliveMillis {
+ type uint32;
+ }
+
+ container threadFactory {
+ uses config:service-ref {
+ refine type {
+ // mandatory true;
+ config:required-identity th:threadfactory;
+ }
+ }
+ }
+ }
+ }
+
+ identity threadpool-scheduled {
+ base config:module-type;
+ config:provided-service th:scheduled-threadpool;
+ config:java-name-prefix ScheduledThreadPool;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadpool-scheduled {
+ when "/config:modules/config:module/config:type = 'threadpool-scheduled'";
+ leaf max-thread-count {
+ type uint16;
+ }
+
+ container threadFactory {
+ uses config:service-ref {
+ refine type {
+ // mandatory true;
+ config:required-identity th:threadfactory;
+ }
+ }
+ }
+ }
+ }
}
<version>2.4</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.opendaylight.yangtools.thirdparty</groupId>
<artifactId>antlr4-runtime-osgi-nohead</artifactId>
<version>4.0</version>
<artifactId>yang-model-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>yang-ext</artifactId>
- </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>yang-ext</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ </dependency>
</dependencies>
</profile>
</profiles>
<Import-Package>
org.opendaylight.controller.sal.binding.api,
org.opendaylight.controller.sal.binding.api.data,
- org.opendaylight.controller.md.sal.common.api.data,
- org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow,
+ org.opendaylight.controller.md.sal.common.api.data,
+ org.opendaylight.controller.sal.utils,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.bucket,
org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819,
+ org.opendaylight.controller.clustering.services, org.opendaylight.controller.sal.core,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction,
+ org.opendaylight.controller.switchmanager,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024,
org.opendaylight.yangtools.concepts,
org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819,
org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819,
package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.NotificationService;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.IContainer;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FRMConsumerImpl extends AbstractBindingAwareProvider {
+public class FRMConsumerImpl extends AbstractBindingAwareProvider implements CommandProvider{
protected static final Logger logger = LoggerFactory.getLogger(FRMConsumerImpl.class);
private static ProviderContext p_session;
private static DataBrokerService dataBrokerService;
private GroupConsumerImpl groupImplRef;
private static DataProviderService dataProviderService;
+ private static IClusterContainerServices clusterContainerService = null;
+ private static ISwitchManager switchManager;
+ private static IContainer container;
+
@Override
public void onSessionInitiated(ProviderContext session) {
FRMConsumerImpl.p_session = session;
+ if (!getDependentModule()) {
+ logger.error("Unable to fetch handlers for dependent modules");
+ System.out.println("Unable to fetch handlers for dependent modules");
+ return;
+ }
+
if (null != session) {
notificationService = session.getSALService(NotificationService.class);
if (null != dataProviderService) {
flowImplRef = new FlowConsumerImpl();
- groupImplRef = new GroupConsumerImpl();
+ // groupImplRef = new GroupConsumerImpl();
+ registerWithOSGIConsole();
}
else {
logger.error("Data Provider Service is down or NULL. " +
System.out.println("Consumer session is NULL. Please check if provider is registered");
}
+ }
+
+ public static IClusterContainerServices getClusterContainerService() {
+ return clusterContainerService;
+ }
+
+ public static void setClusterContainerService(
+ IClusterContainerServices clusterContainerService) {
+ FRMConsumerImpl.clusterContainerService = clusterContainerService;
+ }
+
+ public static ISwitchManager getSwitchManager() {
+ return switchManager;
+ }
+
+ public static void setSwitchManager(ISwitchManager switchManager) {
+ FRMConsumerImpl.switchManager = switchManager;
+ }
+
+ public static IContainer getContainer() {
+ return container;
}
- public static DataProviderService getDataProviderService() {
+ public static void setContainer(IContainer container) {
+ FRMConsumerImpl.container = container;
+ }
+
+ private void registerWithOSGIConsole() {
+ BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ bundleContext.registerService(CommandProvider.class.getName(), this, null);
+ }
+
+ private boolean getDependentModule() {
+ do {
+ clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance(IClusterContainerServices.class, this);
+ try {
+ Thread.sleep(4);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } while(clusterContainerService == null);
+
+ do {
+
+
+ container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
+ try {
+ Thread.sleep(5);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } while (container == null);
+
+ do {
+ switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, container.getName(), this);
+ try {
+ Thread.sleep(5);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ } while(null == switchManager);
+ return true;
+ }
+
+
+
+ public static DataProviderService getDataProviderService() {
return dataProviderService;
}
public FlowConsumerImpl getFlowImplRef() {
- return flowImplRef;
+ return flowImplRef;
}
public GroupConsumerImpl getGroupImplRef() {
- return groupImplRef;
+ return groupImplRef;
}
public static ProviderContext getProviderSession() {
public static DataBrokerService getDataBrokerService() {
return dataBrokerService;
}
+
+ /*
+ * OSGI COMMANDS
+ */
+ @Override
+ public String getHelp() {
+ StringBuffer help = new StringBuffer();
+ return help.toString();
+ }
}
--- /dev/null
+package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.bucket.Actions;
+
+public class FRMUtil {
+ private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
+ public enum operation {ADD, DELETE, UPDATE, GET};
+
+
+ public static boolean isNameValid(String name) {
+
+ // Name validation
+ if (name == null || name.trim().isEmpty() || !name.matches(NAMEREGEX)) {
+ return false;
+ }
+ return true;
+
+ }
+
+ public static boolean areActionsValid(Actions actions) {
+ // List<Action> actionList;
+ // Action actionRef;
+ // if (null != actions && null != actions.getAction()) {
+ // actionList = actions.getAction();
+
+
+
+
+ // }
+
+ return true;
+ }
+}
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
}
listener = new FlowDataListener();
+
if (null == FRMConsumerImpl.getDataBrokerService().registerDataChangeListener(path, listener)) {
logger.error("Failed to listen on flow data modifcation events");
System.out.println("Consumer SAL Service is down or NULL.");
System.out.println("Consumer SAL Service is down or NULL.");
return;
}
- addFlowTest();
+ //addFlowTest();
System.out.println("-------------------------------------------------------------------");
allocateCaches();
commitHandler = new FlowDataCommitHandler();
private void addFlow(InstanceIdentifier<?> path, Flow dataObject) {
AddFlowInputBuilder input = new AddFlowInputBuilder();
+ List<Instruction> inst = (dataObject).getInstructions().getInstruction();
input.setNode((dataObject).getNode());
input.setPriority((dataObject).getPriority());
input.setMatch((dataObject).getMatch());
input.setCookie((dataObject).getCookie());
- input.setAction((dataObject).getAction());
+ input.setInstructions((dataObject).getInstructions());
+ dataObject.getMatch().getLayer3Match()
+ for (int i=0;i<inst.size();i++) {
+ System.out.println("i = "+ i + inst.get(i).getInstruction().toString());
+ System.out.println("i = "+ i + inst.get(i).toString());
+ }
+
+ System.out.println("Instruction list" + (dataObject).getInstructions().getInstruction().toString());
// We send flow to the sounthbound plugin
flowService.addFlow(input.build());
private void commitToPlugin(internalTransaction transaction) {
for(Entry<InstanceIdentifier<?>, Flow> entry :transaction.additions.entrySet()) {
+ System.out.println("Coming add cc in FlowDatacommitHandler");
addFlow(entry.getKey(),entry.getValue());
}
- for(@SuppressWarnings("unused") Entry<InstanceIdentifier<?>, Flow> entry :transaction.additions.entrySet()) {
+ for(@SuppressWarnings("unused") Entry<InstanceIdentifier<?>, Flow> entry :transaction.updates.entrySet()) {
+ System.out.println("Coming update cc in FlowDatacommitHandler");
// updateFlow(entry.getKey(),entry.getValue());
}
Flow original = originalSwView.get(key);
if (original != null) {
// It is update for us
+ System.out.println("Coming update in FlowDatacommitHandler");
updates.put(key, flow);
} else {
// It is addition for us
+ System.out.println("Coming add in FlowDatacommitHandler");
additions.put(key, flow);
}
}
for (DataObject dataObject : additions) {
if (dataObject instanceof NodeFlow) {
NodeRef nodeOne = createNodeRef("foo:node:1");
- // validating the dataObject here
+ // validating the dataObject here
AddFlowInputBuilder input = new AddFlowInputBuilder();
input.setNode(((NodeFlow) dataObject).getNode());
input.setNode(nodeOne);
return new NodeRef(path);
}
- /* private void loadFlowData() {
- DataModification modification = (DataModification) dataservice.beginTransaction();
- String id = "abc";
- FlowKey key = new FlowKey(id, new NodeRef());
- InstanceIdentifier<?> path1;
- FlowBuilder flow = new FlowBuilder();
- flow.setKey(key);
- path1 = InstanceIdentifier.builder().node(Flows.class).node(Flow.class, key).toInstance();
- DataObject cls = (DataObject) modification.readConfigurationData(path);
- modification.putConfigurationData(path, flow.build());
- modification.commit();
- }*/
}
package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.IContainer;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.Groups;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAdded;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes.GroupType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("unused")
public class GroupConsumerImpl {
- public GroupConsumerImpl() {
-
+
+ protected static final Logger logger = LoggerFactory.getLogger(GroupConsumerImpl.class);
+ private GroupEventListener groupEventListener = new GroupEventListener();
+ private Registration<NotificationListener> groupListener;
+ private SalGroupService groupService;
+ private GroupDataCommitHandler commitHandler;
+
+ private ConcurrentMap<GroupKey, Group> originalSwGroupView;
+ private ConcurrentMap<GroupKey, Group> installedSwGroupView;
+
+ private ConcurrentMap<Node, List<Group>> nodeGroups;
+ private ConcurrentMap<GroupKey, Group> inactiveGroups;
+
+ private IClusterContainerServices clusterGroupContainerService = null;
+ private ISwitchManager switchGroupManager;
+ private IContainer container;
+
+ public GroupConsumerImpl() {
+ InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class).toInstance();
+ groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
+
+ clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
+ switchGroupManager = FRMConsumerImpl.getSwitchManager();
+ container = FRMConsumerImpl.getContainer();
+
+ if (!(cacheStartup())) {
+ logger.error("Unanle to allocate/retrieve group cache");
+ System.out.println("Unable to allocate/retrieve group cache");
+ }
+
+ if (null == groupService) {
+ logger.error("Consumer SAL Group Service is down or NULL. FRM may not function as intended");
+ System.out.println("Consumer SAL Group Service is down or NULL.");
+ return;
+ }
+
+ // For switch events
+ groupListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(groupEventListener);
+
+ if (null == groupListener) {
+ logger.error("Listener to listen on group data modifcation events");
+ System.out.println("Listener to listen on group data modifcation events.");
+ return;
+ }
+
+ commitHandler = new GroupDataCommitHandler();
+ FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
}
+
+ private boolean allocateGroupCaches() {
+ if (this.clusterGroupContainerService == null) {
+ logger.warn("Group: Un-initialized clusterGroupContainerService, can't create cache");
+ return false;
+ }
+
+ try {
+ clusterGroupContainerService.createCache("frm.originalSwGroupView",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ clusterGroupContainerService.createCache("frm.installedSwGroupView",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ clusterGroupContainerService.createCache("frm.inactiveGroups",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ clusterGroupContainerService.createCache("frm.nodeGroups",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+//TODO for cluster mode
+ /* clusterGroupContainerService.createCache(WORK_STATUS_CACHE,
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));
+
+ clusterGroupContainerService.createCache(WORK_ORDER_CACHE,
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));*/
+
+ } catch (CacheConfigException cce) {
+ logger.error("Group CacheConfigException");
+ return false;
+
+ } catch (CacheExistException cce) {
+ logger.error(" Group CacheExistException");
+ }
+
+ return true;
+ }
+
+ private void nonClusterGroupObjectCreate() {
+ originalSwGroupView = new ConcurrentHashMap<GroupKey, Group>();
+ installedSwGroupView = new ConcurrentHashMap<GroupKey, Group>();
+ nodeGroups = new ConcurrentHashMap<Node, List<Group>>();
+ inactiveGroups = new ConcurrentHashMap<GroupKey, Group>();
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private boolean retrieveGroupCaches() {
+ ConcurrentMap<?, ?> map;
+
+ if (this.clusterGroupContainerService == null) {
+ logger.warn("Group: un-initialized clusterGroupContainerService, can't retrieve cache");
+ nonClusterGroupObjectCreate();
+ return false;
+ }
+
+ map = clusterGroupContainerService.getCache("frm.originalSwGroupView");
+ if (map != null) {
+ originalSwGroupView = (ConcurrentMap<GroupKey, Group>) map;
+ } else {
+ logger.error("Retrieval of cache(originalSwGroupView) failed");
+ return false;
+ }
+
+ map = clusterGroupContainerService.getCache("frm.installedSwGroupView");
+ if (map != null) {
+ installedSwGroupView = (ConcurrentMap<GroupKey, Group>) map;
+ } else {
+ logger.error("Retrieval of cache(installedSwGroupView) failed");
+ return false;
+ }
+
+ map = clusterGroupContainerService.getCache("frm.inactiveGroups");
+ if (map != null) {
+ inactiveGroups = (ConcurrentMap<GroupKey, Group>) map;
+ } else {
+ logger.error("Retrieval of cache(inactiveGroups) failed");
+ return false;
+ }
+
+ map = clusterGroupContainerService.getCache("frm.nodeGroups");
+ if (map != null) {
+ nodeGroups = (ConcurrentMap<Node, List<Group>>) map;
+ } else {
+ logger.error("Retrieval of cache(nodeGroup) failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean cacheStartup() {
+ if (allocateGroupCaches()) {
+ if (retrieveGroupCaches()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public Status validateGroup(Group group, FRMUtil.operation operation) {
+ String containerName;
+ String groupName;
+ Iterator<Bucket> bucketIterator;
+ boolean returnResult;
+ Buckets groupBuckets;
+
+ if (null != group) {
+ containerName = group.getContainerName();
+
+ if (null == containerName) {
+ containerName = GlobalConstants.DEFAULT.toString();
+ }
+ else if (!FRMUtil.isNameValid(containerName)) {
+ logger.error("Container Name is invalid %s" + containerName);
+ return new Status(StatusCode.BADREQUEST, "Container Name is invalid");
+ }
+
+ groupName = group.getGroupName();
+ if (!FRMUtil.isNameValid(groupName)) {
+ logger.error("Group Name is invalid %s" + groupName);
+ return new Status(StatusCode.BADREQUEST, "Group Name is invalid");
+ }
+
+ returnResult = doesGroupEntryExists(group.getKey(), groupName, containerName);
+
+ if (FRMUtil.operation.ADD == operation && returnResult) {
+ logger.error("Record with same Group Name exists");
+ return new Status(StatusCode.BADREQUEST, "Group record exists");
+ }
+ else if (!returnResult) {
+ logger.error("Group record does not exist");
+ return new Status(StatusCode.BADREQUEST, "Group record does not exist");
+ }
+
+ if (!(group.getGroupType().getIntValue() >= GroupType.GroupAll.getIntValue() &&
+ group.getGroupType().getIntValue() <= GroupType.GroupFf.getIntValue())) {
+ logger.error("Invalid Group type %d" + group.getGroupType().getIntValue());
+ return new Status(StatusCode.BADREQUEST, "Invalid Group type");
+ }
+
+ groupBuckets = group.getBuckets();
+
+ if (null != groupBuckets && null != groupBuckets.getBucket()) {
+ bucketIterator = groupBuckets.getBucket().iterator();
+
+ while (bucketIterator.hasNext()) {
+ if(!(FRMUtil.areActionsValid(bucketIterator.next().getActions()))) {
+ logger.error("Error in action bucket");
+ return new Status(StatusCode.BADREQUEST, "Invalid Group bucket contents");
+ }
+ }
+ }
+ }
+
+ return new Status(StatusCode.SUCCESS);
+
+ }
+
+ private boolean doesGroupEntryExists(GroupKey key, String groupName, String containerName) {
+ if (! originalSwGroupView.containsKey(key)) {
+ return false;
+ }
+
+ for (ConcurrentMap.Entry<GroupKey, Group> entry : originalSwGroupView.entrySet()) {
+ if (entry.getValue().getGroupName().equals(groupName)) {
+ if (entry.getValue().getContainerName().equals(containerName)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Update Group entries to the southbound plugin/inventory and our internal database
+ *
+ * @param path
+ * @param dataObject
+ */
+ private Status updateGroup(InstanceIdentifier<?> path, Group groupUpdateDataObject) {
+ GroupKey groupKey = groupUpdateDataObject.getKey();
+ Status groupOperationStatus = validateGroup(groupUpdateDataObject, FRMUtil.operation.UPDATE);
+
+ if (!groupOperationStatus.isSuccess()) {
+ logger.error("Group data object validation failed %s" + groupUpdateDataObject.getGroupName());
+ return groupOperationStatus;
+ }
+
+ originalSwGroupView.remove(groupKey);
+ originalSwGroupView.put(groupKey, groupUpdateDataObject);
+
+ if (groupUpdateDataObject.isInstall()) {
+ UpdateGroupInputBuilder groupData = new UpdateGroupInputBuilder();
+ //TODO how to get original group and modified group.
+
+ if (installedSwGroupView.containsKey(groupKey)) {
+ installedSwGroupView.remove(groupKey);
+ }
+
+ installedSwGroupView.put(groupKey, groupUpdateDataObject);
+ groupService.updateGroup(groupData.build());
+ }
+
+ return groupOperationStatus;
+ }
+
+ /**
+ * Adds Group to the southbound plugin and our internal database
+ *
+ * @param path
+ * @param dataObject
+ */
+ private Status addGroup(InstanceIdentifier<?> path, Group groupAddDataObject) {
+ GroupKey groupKey = groupAddDataObject.getKey();
+ Status groupOperationStatus = validateGroup(groupAddDataObject, FRMUtil.operation.ADD);
+
+ if (!groupOperationStatus.isSuccess()) {
+ logger.error("Group data object validation failed %s" + groupAddDataObject.getGroupName());
+ return groupOperationStatus;
+ }
+ validateGroup(groupAddDataObject, FRMUtil.operation.ADD);
+ originalSwGroupView.put(groupKey, groupAddDataObject);
+
+ if (groupAddDataObject.isInstall()) {
+ AddGroupInputBuilder groupData = new AddGroupInputBuilder();
+ groupData.setBuckets(groupAddDataObject.getBuckets());
+ groupData.setContainerName(groupAddDataObject.getContainerName());
+ groupData.setGroupId(groupAddDataObject.getGroupId());
+ groupData.setGroupType(groupAddDataObject.getGroupType());
+ groupData.setNode(groupAddDataObject.getNode());
+ installedSwGroupView.put(groupKey, groupAddDataObject);
+ groupService.addGroup(groupData.build());
+ }
+
+ return groupOperationStatus;
+ }
+
+ private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
+ for(Entry<InstanceIdentifier<?>, Group> entry :transaction.additions.entrySet()) {
+
+ if (!addGroup(entry.getKey(),entry.getValue()).isSuccess()) {
+ return Rpcs.getRpcResult(false, null, null);
+ }
+ }
+ for(@SuppressWarnings("unused") Entry<InstanceIdentifier<?>, Group> entry :transaction.additions.entrySet()) {
+
+ if (!updateGroup(entry.getKey(),entry.getValue()).isSuccess()) {
+ return Rpcs.getRpcResult(false, null, null);
+ }
+ }
+
+ for(InstanceIdentifier<?> removal : transaction.removals) {
+ // removeFlow(removal);
+ }
+
+ return Rpcs.getRpcResult(true, null, null);
+ }
+
+ private final class GroupDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+ // We should verify transaction
+ System.out.println("Coming in FlowDatacommitHandler");
+ internalTransaction transaction = new internalTransaction(modification);
+ transaction.prepareUpdate();
+ return transaction;
+ }
+ }
+
+ private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
+
+ private final DataModification<InstanceIdentifier<?>, DataObject> modification;
+
+ @Override
+ public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
+ return modification;
+ }
+
+ public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+ this.modification = modification;
+ }
+
+ Map<InstanceIdentifier<?>, Group> additions = new HashMap<>();
+ Map<InstanceIdentifier<?>, Group> updates = new HashMap<>();
+ Set<InstanceIdentifier<?>> removals = new HashSet<>();
+
+ /**
+ * We create a plan which flows will be added, which will be updated and
+ * which will be removed based on our internal state.
+ *
+ */
+ void prepareUpdate() {
+
+ Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
+ for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
+ if (entry.getValue() instanceof Group) {
+ Group group = (Group) entry.getValue();
+ preparePutEntry(entry.getKey(), group);
+ }
+
+ }
+
+ removals = modification.getRemovedConfigurationData();
+ }
+
+ private void preparePutEntry(InstanceIdentifier<?> key, Group group) {
+
+ Group original = originalSwGroupView.get(key);
+ if (original != null) {
+ // It is update for us
+
+ updates.put(key, group);
+ } else {
+ // It is addition for us
+
+ additions.put(key, group);
+ }
+ }
+
+ /**
+ * We are OK to go with execution of plan
+ *
+ */
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+
+ RpcResult<Void> rpcStatus = commitToPlugin(this);
+ // We return true if internal transaction is successful.
+ // return Rpcs.getRpcResult(true, null, Collections.emptySet());
+ return rpcStatus;
+ }
+
+ /**
+ *
+ * We should rollback our preparation
+ *
+ */
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ // NOOP - we did not modified any internal state during
+ // requestCommit phase
+ // return Rpcs.getRpcResult(true, null, Collections.emptySet());
+ return Rpcs.getRpcResult(true, null, null);
+
+ }
+
+ }
+
+
+ final class GroupEventListener implements SalGroupListener {
+
+ List<GroupAdded> addedGroups = new ArrayList<>();
+ List<GroupRemoved> removedGroups = new ArrayList<>();
+ List<GroupUpdated> updatedGroups = new ArrayList<>();
+
+
+ @Override
+ public void onGroupAdded(GroupAdded notification) {
+ System.out.println("added Group..........................");
+ addedGroups.add(notification);
+ }
+
+ @Override
+ public void onGroupRemoved(GroupRemoved notification) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onGroupUpdated(GroupUpdated notification) {
+ // TODO Auto-generated method stub
+
+ }
+ }
}
--- /dev/null
+package org.opendaylight.controller.md.compatibility.inventory
+
+import org.opendaylight.controller.switchmanager.ISwitchManager
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
+import java.util.ArrayList
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
+import static extension org.opendaylight.controller.sal.compatibility.InventoryMapping.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder
+
+class InventoryReader implements RuntimeDataProvider {
+
+ @Property
+ var ISwitchManager switchManager;
+
+ override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+
+ // Topology and Inventory are operational only
+ return null;
+ }
+
+ override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ val type = path.targetType;
+ var DataObject data = null;
+ switch (type) {
+ case Nodes:
+ data = readNodes(path as InstanceIdentifier<Nodes>)
+ case Node:
+ data = readNode(path as InstanceIdentifier<Node>)
+ case NodeConnector:
+ data = readNodeConnector(path as InstanceIdentifier<NodeConnector>)
+ }
+ return data;
+ }
+
+ def DataObject readNodeConnector(InstanceIdentifier<NodeConnector> identifier) {
+ val nodeConnector = identifier.toAdNodeConnector();
+ return constructNodeConnector(nodeConnector)
+ }
+
+ def DataObject readNode(InstanceIdentifier<Node> identifier) {
+ val node = identifier.toAdNode();
+ return constructNode(node);
+ }
+
+
+ def Node constructNode(org.opendaylight.controller.sal.core.Node node) {
+ val connectors = switchManager.getNodeConnectors(node)
+
+ val tpList = new ArrayList<NodeConnector>(connectors.size)
+ for (connector : connectors) {
+ tpList.add(constructNodeConnector(connector));
+ }
+
+ val it = new NodeBuilder()
+ key = node.toNodeKey();
+ nodeConnector = tpList
+ return build();
+ }
+
+ def NodeConnector constructNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector) {
+ val it = new NodeConnectorBuilder()
+ key = connector.toNodeConnectorKey()
+ return build();
+ }
+
+ def readNodes(InstanceIdentifier<Nodes> identifier) {
+ val nodes = switchManager.nodes
+ val nodeList = new ArrayList<Node>(nodes.size)
+ for (node : nodes) {
+ nodeList.add(constructNode(node))
+ }
+ val it = new NodesBuilder();
+ node = nodeList
+ return build()
+
+ }
+}
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
-
+import org.opendaylight.controller.sal.compatibility.InventoryMapping
class TopologyMapping {
new(TopologyKey path, InstanceIdentifier<Topology> key) {
def Edge toAdTopologyEdge(InstanceIdentifier<Link> identifier) {
val linkKey = (identifier.path.last as IdentifiableItem<Link,LinkKey>).key;
val components = linkKey.linkId.value.split("::::");
- val tail = nodeConnectorFromString(components.get(0).split("::"));
- val head = nodeConnectorFromString(components.get(1).split("::"));
+ val tail = InventoryMapping.nodeConnectorFromId(components.get(0));
+ val head = InventoryMapping.nodeConnectorFromId(components.get(1));
return new Edge(tail, head);
}
def NodeConnector toAdTopologyNodeConnector(InstanceIdentifier<TerminationPoint> identifier) {
val tpKey = (identifier.path.last as IdentifiableItem<TerminationPoint,TerminationPointKey>).key;
- return nodeConnectorFromString(tpKey.tpId.value.split("::"));
+ return InventoryMapping.nodeConnectorFromId(tpKey.tpId.value);
}
def org.opendaylight.controller.sal.core.Node toAdTopologyNode(
InstanceIdentifier<Node> identifier) {
val tpKey = (identifier.path.last as IdentifiableItem<Node,NodeKey>).key;
- return nodeFromString(tpKey.nodeId.value.split("::"));
+ return InventoryMapping.nodeFromNodeId(tpKey.nodeId.value);
}
def NodeKey toTopologyNodeKey(org.opendaylight.controller.sal.core.Node node) {
- val nodeId = new NodeId('''ad-sal:«node.type»::«node.nodeIDString»''')
+ val nodeId = new NodeId(InventoryMapping.toNodeId(node));
return new NodeKey(nodeId);
}
def TerminationPointKey toTopologyTerminationPointKey(NodeConnector nc) {
val node = nc.node;
- val nodeId = new TpId('''ad-sal:«node.type»::«node.nodeIDString»::«nc.nodeConnectorIDString»''')
+ val nodeId = new TpId(InventoryMapping.toNodeConnectorId(nc))
return new TerminationPointKey(nodeId);
}
val linkId = new LinkId('''«sourceTp.tpId»::::«destTp.tpId»''')
return new LinkKey(linkId);
}
-
- def NodeConnector nodeConnectorFromString(String[] string) {
- val node = nodeFromString(string.subList(0,1));
- return NodeConnector.fromStringNoNode(string.get(2),node);
- }
-
- def org.opendaylight.controller.sal.core.Node nodeFromString(String[] strings) {
- val type = strings.get(0).substring(6);
- org.opendaylight.controller.sal.core.Node.fromString(type,strings.get(1))
- }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+package org.opendaylight.controller.sal.compatibility
+
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
+
+class InventoryMapping {
+
+ static def org.opendaylight.controller.sal.core.NodeConnector toAdNodeConnector(
+ InstanceIdentifier<NodeConnector> identifier) {
+ val tpKey = (identifier.path.last as IdentifiableItem<NodeConnector,NodeConnectorKey>).key;
+ return nodeConnectorFromId(tpKey.id.value);
+ }
+
+ static def org.opendaylight.controller.sal.core.Node toAdNode(InstanceIdentifier<Node> identifier) {
+ val tpKey = (identifier.path.last as IdentifiableItem<Node,NodeKey>).key;
+ return nodeFromNodeId(tpKey.id.value);
+ }
+
+
+ static def NodeRef toNodeRef(org.opendaylight.controller.sal.core.Node node) {
+ val nodeId = new NodeKey(new NodeId(node.toNodeId))
+ val path = InstanceIdentifier.builder().node(Nodes).child(Node,nodeId).toInstance;
+ return new NodeRef(path);
+ }
+
+ static def NodeKey toNodeKey(org.opendaylight.controller.sal.core.Node node) {
+ val nodeId = new NodeId(node.toNodeId)
+ return new NodeKey(nodeId);
+ }
+
+ static def NodeConnectorKey toNodeConnectorKey(org.opendaylight.controller.sal.core.NodeConnector nc) {
+ val nodeId = new NodeConnectorId(nc.toNodeConnectorId)
+ return new NodeConnectorKey(nodeId);
+ }
+
+ static def String toNodeId(org.opendaylight.controller.sal.core.Node node) {
+ '''ad-sal:«node.type»::«node.nodeIDString»'''
+ }
+
+ static def String toNodeConnectorId(org.opendaylight.controller.sal.core.NodeConnector nc) {
+ '''«nc.node.toNodeId»::«nc.nodeConnectorIDString»'''
+ }
+
+ static def org.opendaylight.controller.sal.core.Node nodeFromNodeId(String nodeId) {
+ return nodeFromString(nodeId.split("::"))
+ }
+
+ static def nodeConnectorFromId(String invId) {
+ return nodeConnectorFromString(invId.split("::"));
+ }
+
+ private static def org.opendaylight.controller.sal.core.NodeConnector nodeConnectorFromString(String[] string) {
+ val node = nodeFromString(string.subList(0, 1));
+ return org.opendaylight.controller.sal.core.NodeConnector.fromStringNoNode(string.get(2), node);
+ }
+
+ private static def org.opendaylight.controller.sal.core.Node nodeFromString(String[] strings) {
+ val type = strings.get(0).substring(6);
+ org.opendaylight.controller.sal.core.Node.fromString(type, strings.get(1))
+ }
+
+}
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.common.util.Futures;
import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.compatibility.InventoryMapping;
import org.opendaylight.controller.sal.compatibility.NodeMapping;
import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
import org.opendaylight.controller.sal.core.ConstructionException;
-import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerListener;
import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private NotificationProviderService publish;
@Override
- public void flowRemoved(Node node, Flow flow) {
+ public void flowRemoved(org.opendaylight.controller.sal.core.Node node, Flow flow) {
FlowRemovedBuilder flowRemovedBuilder = new FlowRemovedBuilder();
- flowRemovedBuilder.setNode(NodeMapping.toNodeRef(node));
+ flowRemovedBuilder.setNode(InventoryMapping.toNodeRef(node));
publish.publish(flowRemovedBuilder.build());
}
@Override
- public void flowErrorReported(Node node, long rid, Object err) {
+ public void flowErrorReported(org.opendaylight.controller.sal.core.Node node, long rid, Object err) {
// TODO Auto-generated method stub
}
@Override
public Future<RpcResult<Void>> addFlow(AddFlowInput input) {
- try {
- Flow flow = ToSalConversionsUtils.toFlow(input);
- Node node = NodeMapping.toADNode(input.getNode());
- Status status = delegate.addFlowAsync(node, flow);
- Void rpcResultType = null;
- return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
- return null;
+
+ Flow flow = ToSalConversionsUtils.toFlow(input);
+ @SuppressWarnings("unchecked")
+ org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
+ .getNode().getValue());
+ Status status = delegate.addFlowAsync(node, flow);
+ Void rpcResultType = null;
+ return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
}
@Override
public Future<RpcResult<Void>> removeFlow(RemoveFlowInput input) {
- try {
- Flow flow = ToSalConversionsUtils.toFlow(input);
- Node node = NodeMapping.toADNode(input.getNode());
- Status status = delegate.removeFlowAsync(node, flow);
- Void rpcResultType = null;
- return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
- return null;
+
+ Flow flow = ToSalConversionsUtils.toFlow(input);
+ @SuppressWarnings("unchecked")
+ org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
+ .getNode().getValue());
+ Status status = delegate.removeFlowAsync(node, flow);
+ Void rpcResultType = null;
+ return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+
}
@Override
public Future<RpcResult<Void>> updateFlow(UpdateFlowInput input) {
- try {
- Node node = NodeMapping.toADNode(input.getNode());
- Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow());
- Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow());
- Status status = delegate.modifyFlowAsync(node, originalFlow, updatedFlow);
- Void rpcResultType = null;
- return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
- return null;
+ @SuppressWarnings("unchecked")
+ org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
+ .getNode().getValue());
+ Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow());
+ Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow());
+ Status status = delegate.modifyFlowAsync(node, originalFlow, updatedFlow);
+ Void rpcResultType = null;
+ return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
}
}
-package org.opendaylight.controller.sal.compability;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+*
+* This program and the accompanying materials are 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
+*/
+package org.opendaylight.controller.sal.compatibility.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-package org.opendaylight.controller.sal.compability;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+package org.opendaylight.controller.sal.compatibility.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
type string;
}
+ leaf barrier {
+ type boolean;
+ }
+
container buckets {
list bucket {
key "order";
type meter-id;
}
+ leaf install {
+ type boolean;
+ }
+ leaf meter-name {
+ type string;
+ }
+
+ leaf container-name {
+ type string;
+ }
+
container meter-band-headers {
list meter-band-header {
key "order";
}
typedef port-state {
- type enumeration {
- enum link-down;
- enum blocked;
- enum live;
+ type enumeration {
+ enum link-down;
+ enum blocked;
+ enum live;
}
}
uses common-port;
leaf mask {
- type uint32;
+ type port-config;
description "Bitmap of OFPPC-* flags to be changed";
}
leaf port-name {
type string;
- }
+ }
+
+ leaf barrier {
+ type boolean;
+ }
}
}
}
}
grouping meter-entry {
-
leaf node {
type inv:node-ref;
}
-
uses meter:meter;
}
--- /dev/null
+module flow-capable-transaction {
+ namespace "urn:opendaylight:flow:transaction";
+ prefix type;
+
+ import opendaylight-inventory {prefix inv; revision-date "2013-08-19";}
+ import yang-ext {prefix ext; revision-date "2013-07-09";}
+
+ revision "2013-11-03" {
+ description "Initial revision";
+ }
+
+ typedef transaction-id {
+ type uint64;
+ }
+
+ grouping transaction-aware {
+ leaf transaction-id {
+ type transaction-id;
+ }
+ }
+
+ rpc get-next-transaction-id {
+ input {
+ leaf node {
+ ext:context-reference "inv:node-context";
+ type inv:node-ref;
+ }
+ }
+ output {
+ uses transaction-aware;
+ }
+ }
+
+ // Barier request?
+ rpc finish-transaction {
+ input {
+ leaf node {
+ ext:context-reference "inv:node-context";
+ type inv:node-ref;
+ }
+ leaf transaction-id {
+ type transaction-id;
+ }
+ }
+ }
+}
\ No newline at end of file
import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
import ietf-inet-types {prefix inet;revision-date 2010-09-24;}
import opendaylight-group-types {prefix group-type;revision-date 2013-10-18;}
+ import flow-capable-transaction {prefix tr;}
revision "2013-09-18" {
description "Initial revision of group service";
}
grouping node-group {
- uses "inv:node-context-ref";
-
+ uses "inv:node-context-ref";
uses group-type:group;
}
rpc add-group {
input {
uses node-group;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
rpc remove-group {
input {
uses group-update;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
rpc update-group {
input {
uses group-update;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
import yang-ext {prefix ext; revision-date "2013-07-09";}
import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
import opendaylight-meter-types {prefix meter-type;revision-date "2013-09-18";}
+ import flow-capable-transaction {prefix tr;}
revision "2013-09-18" {
description "Initial revision of meter service";
rpc add-meter {
input {
uses node-meter;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
rpc remove-meter {
input {
uses node-meter;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
rpc update-meter {
input {
uses meter-update;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
--- /dev/null
+module sal-port {
+ namespace "urn:opendaylight:port:service";
+ prefix port;
+
+ import yang-ext {prefix ext; revision-date "2013-07-09";}
+ import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
+ import opendaylight-port-types {prefix port-type;revision-date "2013-09-25";}
+
+ revision "2013-11-07" {
+ description "Initial revision of port service";
+ }
+
+ grouping node-port {
+ uses "inv:node-context-ref";
+
+ uses port-type:ofp-port-mod;
+ }
+
+ /** Base configuration structure **/
+ grouping port-update {
+ uses "inv:node-context-ref";
+
+ container original-port {
+ uses port-type:ofp-port-mod;
+ }
+ container updated-port {
+ uses port-type:ofp-port-mod;
+ }
+ }
+
+ rpc update-port {
+ input {
+ uses port-update;
+ }
+ }
+
+ rpc get-port {
+ output {
+ uses port-type:flow-capable-port;
+ }
+ }
+
+ notification port-removed {
+ uses node-port;
+ }
+}
\ No newline at end of file
import yang-ext {prefix ext; revision-date "2013-07-09";}
import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
import opendaylight-table-types {prefix table-type;revision-date "2013-10-26";}
+ import flow-capable-transaction {prefix tr;}
revision "2013-10-26" {
description "Initial revision of table service";
- }
+ }
/** Base configuration structure **/
grouping table-update {
+ uses "inv:node-context-ref";
container original-table {
uses table-type:table-features;
}
rpc update-table {
input {
- leaf node {
- ext:context-reference "inv:node-context";
- type inv:node-ref;
- }
uses table-update;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
}
\ No newline at end of file
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>${osgi.core.version}</version>
+ <scope>provided</scope>
</dependency>
</dependencies>
</project>
<configuration>
<instructions>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ <Export-package>
+ org.opendaylight.controller.sal.binding.spi.*,
+ </Export-package>
<Private-Package>
org.opendaylight.controller.config.yang.md.sal.binding.impl,
- org.opendaylight.controller.sal.binding.spi,
- org.opendaylight.controller.sal.binding.spi.*,
org.opendaylight.controller.sal.binding.impl,
org.opendaylight.controller.sal.binding.impl.*,
+ org.opendaylight.controller.sal.binding.codegen,
org.opendaylight.controller.sal.binding.codegen.*,
</Private-Package>
</instructions>
import org.opendaylight.controller.sal.binding.api.data.DataProviderService
import org.opendaylight.yangtools.yang.binding.DataObject
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener
import org.opendaylight.controller.md.sal.common.api.TransactionStatus
-import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification
import org.opendaylight.controller.md.sal.common.api.data.DataReader
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
import org.opendaylight.yangtools.concepts.ListenerRegistration
-import static extension org.opendaylight.controller.sal.binding.impl.util.MapUtils.*;
-import java.util.Collection
-import java.util.Map.Entry
-import java.util.HashSet
-import java.util.Set
import com.google.common.collect.Multimap
import static com.google.common.base.Preconditions.*;
import java.util.List
-import java.util.LinkedList
-import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
import com.google.common.collect.HashMultimap
import java.util.concurrent.ExecutorService
import java.util.concurrent.Callable
import java.util.Collections
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
import java.util.ArrayList
-import org.opendaylight.controller.sal.common.util.RpcErrors
+import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
+import java.util.Arrays
class DataBrokerImpl extends DeprecatedDataAPISupport implements DataProviderService {
@Property
var ExecutorService executor;
- Multimap<InstanceIdentifier, DataReaderRegistration> configReaders = HashMultimap.create();
- Multimap<InstanceIdentifier, DataReaderRegistration> operationalReaders = HashMultimap.create();
+ val dataReadRouter = new BindingAwareDataReaderRouter;
+
Multimap<InstanceIdentifier, DataChangeListenerRegistration> listeners = HashMultimap.create();
Multimap<InstanceIdentifier, DataCommitHandlerRegistration> commitHandlers = HashMultimap.create();
}
override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
- val readers = configReaders.getAllChildren(path);
- return readers.readConfiguration(path);
+ return dataReadRouter.readConfigurationData(path);
}
override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
- val readers = operationalReaders.getAllChildren(path);
- return readers.readOperational(path);
+ return dataReadRouter.readOperationalData(path);
}
override registerCommitHandler(InstanceIdentifier<? extends DataObject> path,
return reg;
}
- override registerDataReader(InstanceIdentifier<? extends DataObject> path,
- DataReader<InstanceIdentifier<? extends DataObject>, DataObject> provider) {
- val ret = new DataReaderRegistration(provider, this);
- ret.paths.add(path);
- configReaders.put(path, ret);
- operationalReaders.put(path, ret);
- return ret;
- }
-
- protected def removeReader(DataReaderRegistration reader) {
- for (path : reader.paths) {
- operationalReaders.remove(path, reader);
- configReaders.remove(path, reader);
- }
+ override registerDataReader(InstanceIdentifier<? extends DataObject> path,DataReader<InstanceIdentifier<? extends DataObject>,DataObject> reader) {
+
+ val confReg = dataReadRouter.registerConfigurationReader(path,reader);
+ val dataReg = dataReadRouter.registerOperationalReader(path,reader);
+
+ return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
}
protected def removeListener(DataChangeListenerRegistration registration) {
protected def removeCommitHandler(DataCommitHandlerRegistration registration) {
commitHandlers.remove(registration.path, registration);
}
-
- protected def DataObject readConfiguration(
- Collection<Entry<? extends InstanceIdentifier, ? extends DataReaderRegistration>> entries,
- InstanceIdentifier<? extends DataObject> path) {
-
- val List<DataObject> partialResults = new LinkedList();
- for (entry : entries) {
- partialResults.add(entry.value.instance.readConfigurationData(path))
- }
- return merge(path, partialResults);
- }
-
- protected def DataObject readOperational(
- Collection<Entry<? extends InstanceIdentifier, ? extends DataReaderRegistration>> entries,
- InstanceIdentifier<? extends DataObject> path) {
-
- val List<DataObject> partialResults = new LinkedList();
- for (entry : entries) {
- partialResults.add(entry.value.instance.readOperationalData(path))
- }
- return merge(path, partialResults);
- }
-
- protected def DataObject merge(InstanceIdentifier<? extends DataObject> identifier, List<DataObject> objects) {
-
- // FIXME: implement real merge
- if (objects.size > 0) {
- return objects.get(0);
- }
- }
protected def getActiveCommitHandlers() {
-
return commitHandlers.entries.map[ value.instance].toSet
}
}
-package class DataReaderRegistration extends //
-AbstractObjectRegistration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> {
-
- DataBrokerImpl dataBroker;
-
- @Property
- val Set<InstanceIdentifier<? extends DataObject>> paths;
-
- new(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> instance, DataBrokerImpl broker) {
- super(instance)
- dataBroker = broker;
- _paths = new HashSet();
- }
-
- override protected removeRegistration() {
- dataBroker.removeReader(this);
- }
-
-}
-
package class DataChangeListenerRegistration extends AbstractObjectRegistration<DataChangeListener> implements ListenerRegistration<DataChangeListener> {
DataBrokerImpl dataBroker;
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are 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
- */
-package org.opendaylight.controller.sal.binding.impl
-
-import org.opendaylight.controller.sal.common.DataStoreIdentifier
-import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
-
-class DataProviderContext {
-
- @Property
- var DataStoreIdentifier identifier;
- @Property
- var RuntimeDataProvider provider;
-}
final DataBrokerImpl broker;
public DataTransactionImpl(DataBrokerImpl dataBroker) {
+ super(dataBroker);
identifier = new Object();
broker = dataBroker;
status = TransactionStatus.NEW;
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.util
+
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+
+class BindingAwareDataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ override protected merge(InstanceIdentifier<? extends DataObject> path, Iterable<DataObject> data) {
+ return data.iterator.next;
+ }
+
+}
\ No newline at end of file
// FIXME: After 0.6 Release of YANGTools refactor to use Path marker interface for arguments.
// import org.opendaylight.yangtools.concepts.Path;
+public interface DataChange<P/* extends Path<P> */, D> {
-public interface DataChange<P/* extends Path<P> */,D> {
+ /**
+ * Returns a map of paths and newly created objects
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getCreatedOperationalData();
- Map<P,D> getCreatedOperationalData();
+ /**
+ * Returns a map of paths and newly created objects
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getCreatedConfigurationData();
- Map<P,D> getUpdatedOperationalData();
+ /**
+ * Returns a map of paths and respective updated objects after update.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalOperationalData()}
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getUpdatedOperationalData();
- Set<P> getRemovedOperationalData();
+ /**
+ * Returns a map of paths and respective updated objects after update.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalConfigurationData()}
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getUpdatedConfigurationData();
- Map<P,D> getCreatedConfigurationData();
- Map<P,D> getUpdatedConfigurationData();
+ /**
+ * Returns a set of paths of removed objects.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalConfigurationData()}
+ *
+ * @return map of paths and newly created objects
+ */
Set<P> getRemovedConfigurationData();
+ /**
+ * Returns a set of paths of removed objects.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalOperationalData()}
+ *
+ * @return map of paths and newly created objects
+ */
+ Set<P> getRemovedOperationalData();
+
+ /**
+ * Return a map of paths and original state of updated and removed objectd.
+ *
+ * @return map of paths and original state of updated and removed objectd.
+ */
+ Map<P, D> getOriginalConfigurationData();
+
+ /**
+ * Return a map of paths and original state of updated and removed objectd.
+ *
+ * @return map of paths and original state of updated and removed objectd.
+ */
+ Map<P, D> getOriginalOperationalData();
}
public interface DataChangeEvent<P,D> extends DataChange<P, D>, Immutable {
+ /**
+ * Returns a new subtree of data, which starts at the path
+ * where listener was registered.
+ *
+ */
+ D getUpdatedConfigurationSubtree();
+
+ /**
+ * Returns a new subtree of data, which starts at the path
+ * where listener was registered.
+ *
+ */
+ D getUpdatedOperationalSubtree();
}
*/
public interface DataCommitHandler<P/* extends Path<P> */,D> {
-
+
DataCommitTransaction<P, D> requestCommit(DataModification<P,D> modification);
public interface DataCommitTransaction<P/* extends Path<P> */,D> {
// import org.opendaylight.yangtools.concepts.Path;
import org.opendaylight.yangtools.yang.common.RpcResult;
-public interface DataModification<P/* extends Path<P> */, D> extends DataReader<P, D> {
+public interface DataModification<P/* extends Path<P> */, D> extends DataChange<P, D>, DataReader<P, D> {
/**
* Returns transaction identifier
TransactionStatus getStatus();
+ /**
+ *
+ * Use {@link #putOperationalData(Object, Object)} instead.
+ *
+ * @param path
+ * @param data
+ */
void putRuntimeData(P path, D data);
+ void putOperationalData(P path, D data);
+
void putConfigurationData(P path, D data);
+ /**
+ * Use {@link #removeOperationalData(Object)}
+ *
+ * @param path
+ */
void removeRuntimeData(P path);
- void removeConfigurationData(P path);
-
- public Map<P, D> getUpdatedConfigurationData();
+ void removeOperationalData(P path);
- public Map<P, D> getUpdatedOperationalData();
-
- public Set<P> getRemovedConfigurationData();
-
- public Set<P> getRemovedOperationalData();
+ void removeConfigurationData(P path);
/**
* Initiates a two-phase commit of modification.
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.data;
+
+public interface DataStore<P, D> extends //
+ DataReader<P, D>, //
+ DataModificationTransactionFactory<P, D> {
+
+ @Override
+ public DataModification<P, D> beginTransaction();
+
+ @Override
+ public D readConfigurationData(P path);
+
+ @Override
+ public D readOperationalData(P path);
+
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import org.opendaylight.yangtools.concepts.Immutable;
+
+public interface Route<C,P> extends Immutable {
+
+ C getType();
+
+ P getPath();
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import java.util.EventListener;
+
+public interface RouteChangeListener<C,P> extends EventListener {
+
+ void onRouteChange(RouteChange<C, P> change);
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+
+public interface RouteChangePublisher<C,P> {
+
+ ListenerRegistration<RouteChangeListener<C,P>> registerRouteChangeListener(RouteChangeListener<C,P> listener);
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import java.util.Map;
+import java.util.Set;
+
+public interface Router<C,P,D> extends //
+ RouteChangePublisher<C, P> {
+
+ Map<C, Set<P>> getAnnouncedPaths();
+}
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
- <Export-Package>org.opendaylight.controller.md.sal.common.impl</Export-Package>
+ <Export-Package>
+ org.opendaylight.controller.md.sal.common.impl,
+ org.opendaylight.controller.md.sal.common.impl.*
+ </Export-Package>
</instructions>
</configuration>
</plugin>
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.yangtools.concepts.Path;
import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.NEW;
-public abstract class AbstractDataModification<P /*extends Path<P>*/, D> implements DataModification<P, D> {
+public abstract class AbstractDataModification<P /* extends Path<P> */, D> implements DataModification<P, D> {
- private final Map<P, D> configurationUpdate;
- private final Map<P, D> operationalUpdate;
+ private final ConcurrentMap<P, D> operationalOriginal;
+ private final ConcurrentMap<P, D> configurationOriginal;
- private final Set<P> configurationRemove;
- private final Set<P> operationalRemove;
+ private final ConcurrentMap<P, D> operationalCreated;
+ private final ConcurrentMap<P, D> configurationCreated;
+ private final ConcurrentMap<P, D> configurationUpdate;
+ private final ConcurrentMap<P, D> operationalUpdate;
+
+ private final ConcurrentMap<P, P> configurationRemove;
+ private final ConcurrentMap<P, P> operationalRemove;
+
+ private final Map<P, D> unmodifiable_configurationOriginal;
+ private final Map<P, D> unmodifiable_operationalOriginal;
+ private final Map<P, D> unmodifiable_configurationCreated;
+ private final Map<P, D> unmodifiable_operationalCreated;
private final Map<P, D> unmodifiable_configurationUpdate;
private final Map<P, D> unmodifiable_operationalUpdate;
private final Set<P> unmodifiable_configurationRemove;
private final Set<P> unmodifiable_OperationalRemove;
+ private DataReader<P, D> reader;
+
+ public AbstractDataModification(DataReader<P, D> reader) {
+ this.reader = reader;
+ this.configurationUpdate = new ConcurrentHashMap<>();
+ this.operationalUpdate = new ConcurrentHashMap<>();
+ this.configurationRemove = new ConcurrentHashMap<>();
+ this.operationalRemove = new ConcurrentHashMap<>();
- public AbstractDataModification(Map<P, D> configurationUpdate, Map<P, D> operationalUpdate,
- Set<P> configurationRemove, Set<P> operationalRemove) {
- this.configurationUpdate = configurationUpdate;
- this.operationalUpdate = operationalUpdate;
- this.configurationRemove = configurationRemove;
- this.operationalRemove = operationalRemove;
+ this.configurationOriginal = new ConcurrentHashMap<>();
+ this.operationalOriginal = new ConcurrentHashMap<>();
+ this.configurationCreated = new ConcurrentHashMap<>();
+ this.operationalCreated = new ConcurrentHashMap<>();
+
+ unmodifiable_configurationOriginal = Collections.unmodifiableMap(configurationOriginal);
+ unmodifiable_operationalOriginal = Collections.unmodifiableMap(operationalOriginal);
+ unmodifiable_configurationCreated = Collections.unmodifiableMap(configurationCreated);
+ unmodifiable_operationalCreated = Collections.unmodifiableMap(operationalCreated);
unmodifiable_configurationUpdate = Collections.unmodifiableMap(configurationUpdate);
unmodifiable_operationalUpdate = Collections.unmodifiableMap(operationalUpdate);
- unmodifiable_configurationRemove = Collections.unmodifiableSet(configurationRemove);
- unmodifiable_OperationalRemove = Collections.unmodifiableSet(operationalRemove);
- }
+ unmodifiable_configurationRemove = Collections.unmodifiableSet(configurationRemove.keySet());
+ unmodifiable_OperationalRemove = Collections.unmodifiableSet(operationalRemove.keySet());
- public AbstractDataModification() {
- this(new HashMap<P, D>(), new HashMap<P, D>(), new HashSet<P>(), new HashSet<P>());
}
@Override
public final void putConfigurationData(P path, D data) {
checkMutable();
+
+ if (!hasConfigurationOriginal(path)) {
+ configurationCreated.put(path, data);
+ }
+
configurationUpdate.put(path, data);
configurationRemove.remove(path);
}
@Override
- public final void putRuntimeData(P path, D data) {
+ public final void putOperationalData(P path, D data) {
checkMutable();
+ if (!hasOperationalOriginal(path)) {
+ operationalCreated.put(path, data);
+ }
operationalUpdate.put(path, data);
operationalRemove.remove(path);
}
@Override
- public final void removeRuntimeData(P path) {
+ public final void putRuntimeData(P path, D data) {
+ putRuntimeData(path, data);
+ }
+
+ @Override
+ public final void removeOperationalData(P path) {
checkMutable();
+ hasOperationalOriginal(path);
operationalUpdate.remove(path);
- operationalRemove.add(path);
+ operationalRemove.put(path, path);
+ }
+
+ @Override
+ public final void removeRuntimeData(P path) {
+ removeOperationalData(path);
}
@Override
public final void removeConfigurationData(P path) {
checkMutable();
+ hasConfigurationOriginal(path);
configurationUpdate.remove(path);
- configurationRemove.add(path);
+ configurationRemove.put(path, path);
}
private final void checkMutable() {
}
@Override
- public Map<P, D> getUpdatedConfigurationData() {
+ public final Map<P, D> getUpdatedConfigurationData() {
return unmodifiable_configurationUpdate;
}
@Override
- public Map<P, D> getUpdatedOperationalData() {
+ public final Map<P, D> getUpdatedOperationalData() {
return unmodifiable_operationalUpdate;
}
@Override
- public Set<P> getRemovedConfigurationData() {
+ public final Set<P> getRemovedConfigurationData() {
return unmodifiable_configurationRemove;
}
@Override
- public Set<P> getRemovedOperationalData() {
+ public final Set<P> getRemovedOperationalData() {
return unmodifiable_OperationalRemove;
}
+ @Override
+ public Map<P, D> getCreatedConfigurationData() {
+ return unmodifiable_configurationCreated;
+ }
+
+ @Override
+ public Map<P, D> getCreatedOperationalData() {
+ return unmodifiable_operationalCreated;
+ }
+
+ @Override
+ public Map<P, D> getOriginalConfigurationData() {
+ return unmodifiable_configurationOriginal;
+ }
+
+ @Override
+ public Map<P, D> getOriginalOperationalData() {
+ return unmodifiable_operationalOriginal;
+ }
+
+ @Override
+ public D readOperationalData(P path) {
+ return reader.readOperationalData(path);
+ }
+
+ @Override
+ public D readConfigurationData(P path) {
+ return reader.readConfigurationData(path);
+ }
+
+ private boolean hasConfigurationOriginal(P path) {
+ if (configurationOriginal.containsKey(path)) {
+ return true;
+ }
+ D data = reader.readConfigurationData(path);
+ if (data != null) {
+ configurationOriginal.putIfAbsent(path, data);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean hasOperationalOriginal(P path) {
+ if (operationalOriginal.containsKey(path)) {
+ return true;
+ }
+ D data = reader.readConfigurationData(path);
+ if (data != null) {
+ operationalOriginal.putIfAbsent(path, data);
+ return true;
+ }
+ return false;
+ }
}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.impl.routing;
+
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.yangtools.concepts.Registration;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Base abstract implementation of DataReadRouter, which performs
+ * a read operation on multiple data readers and then merges result.
+ *
+ * @param <P>
+ * @param <D>
+ */
+public abstract class AbstractDataReadRouter<P extends Path<?>, D> implements DataReader<P, D> {
+
+ Multimap<P, DataReaderRegistration<P, D>> configReaders = HashMultimap.create();
+ Multimap<P, DataReaderRegistration<P, D>> operationalReaders = HashMultimap.create();
+
+ @Override
+ public D readConfigurationData(P path) {
+ FluentIterable<D> dataBits = FluentIterable //
+ .from(getReaders(configReaders, path)).transform(configurationRead(path));
+ return merge(path,dataBits);
+ }
+
+ @Override
+ public D readOperationalData(P path) {
+ FluentIterable<D> dataBits = FluentIterable //
+ .from(getReaders(configReaders, path)).transform(operationalRead(path));
+ return merge(path,dataBits);
+
+ }
+
+ /**
+ * Merges data readed by reader instances from specified path
+ *
+ * @param path Path on which read was performed
+ * @param data Data which was returned by read operation.
+ * @return Merged result.
+ */
+ protected abstract D merge(P path,Iterable<D> data);
+
+ /**
+ * Returns a function which performs configuration read for supplied path
+ *
+ * @param path
+ * @return function which performs configuration read for supplied path
+ */
+
+ private Function<DataReader<P, D>, D> configurationRead(final P path) {
+ return new Function<DataReader<P, D>, D>() {
+ @Override
+ public D apply(DataReader<P, D> input) {
+ return input.readConfigurationData(path);
+ }
+ };
+ }
+
+ /**
+ * Returns a function which performs operational read for supplied path
+ *
+ * @param path
+ * @return function which performs operational read for supplied path
+ */
+ private Function<DataReader<P, D>, D> operationalRead(final P path) {
+ return new Function<DataReader<P, D>, D>() {
+ @Override
+ public D apply(DataReader<P, D> input) {
+ return input.readConfigurationData(path);
+ }
+ };
+ }
+
+ // Registrations
+
+ /**
+ * Register's a reader for operational data.
+ *
+ * @param path Path which is served by this reader
+ * @param reader Reader instance which is responsible for reading particular subpath.
+ * @return
+ */
+ public Registration<DataReader<P, D>> registerOperationalReader(P path, DataReader<P, D> reader) {
+ OperationalDataReaderRegistration<P, D> ret = new OperationalDataReaderRegistration<>(path, reader);
+ operationalReaders.put(path, ret);
+ return ret;
+ }
+
+ public Registration<DataReader<P, D>> registerConfigurationReader(P path, DataReader<P, D> reader) {
+ ConfigurationDataReaderRegistration<P, D> ret = new ConfigurationDataReaderRegistration<>(path, reader);
+ configReaders.put(path, ret);
+ return ret;
+ }
+
+ Iterable<DataReader<P, D>> getOperationalReaders(P path) {
+ return getReaders(operationalReaders, path);
+ }
+
+ Iterable<DataReader<P, D>> getConfigurationReaders(P path) {
+ return getReaders(configReaders, path);
+ }
+
+ private Iterable<DataReader<P, D>> getReaders(Multimap<P, DataReaderRegistration<P, D>> readerMap, P path) {
+ return FluentIterable
+ .from(readerMap.entries()) //
+ .filter(affects(path)) //
+ .transform(retrieveInstance());
+ }
+
+ private void removeRegistration(OperationalDataReaderRegistration<?, ?> registration) {
+ operationalReaders.remove(registration.getKey(), registration);
+ }
+
+ private void removeRegistration(ConfigurationDataReaderRegistration<?, ?> registration) {
+ configReaders.remove(registration.getKey(), registration);
+ }
+
+ private Function<? super Entry<P, DataReaderRegistration<P, D>>, DataReader<P, D>> retrieveInstance() {
+ return new Function<Entry<P, DataReaderRegistration<P, D>>, DataReader<P,D>>() {
+ @Override
+ public DataReader<P, D> apply(Entry<P, DataReaderRegistration<P, D>> input) {
+ return input.getValue().getInstance();
+ }
+ };
+ }
+
+ private Predicate<? super Entry<P, DataReaderRegistration<P, D>>> affects(final P path) {
+
+ return new Predicate<Entry<P, DataReaderRegistration<P, D>>>() {
+
+ @Override
+ public boolean apply(Entry<P, DataReaderRegistration<P, D>> input) {
+ final Path key = input.getKey();
+ return key.contains(path) || ((Path) path).contains(key);
+ }
+
+ };
+ }
+
+ private class ConfigurationDataReaderRegistration<P extends Path<?>, D> extends DataReaderRegistration<P, D> {
+
+ public ConfigurationDataReaderRegistration(P key, DataReader<P, D> instance) {
+ super(key, instance);
+ }
+
+ @Override
+ protected void removeRegistration() {
+ AbstractDataReadRouter.this.removeRegistration(this);
+ }
+ }
+
+ private class OperationalDataReaderRegistration<P extends Path<?>, D> extends DataReaderRegistration<P, D> {
+
+ public OperationalDataReaderRegistration(P key, DataReader<P, D> instance) {
+ super(key, instance);
+ }
+
+ @Override
+ protected void removeRegistration() {
+ AbstractDataReadRouter.this.removeRegistration(this);
+ }
+ }
+
+ private abstract static class DataReaderRegistration<P extends Path<?>, D> extends
+ AbstractObjectRegistration<DataReader<P, D>> {
+
+ private final P key;
+
+ public P getKey() {
+ return this.key;
+ }
+
+ public DataReaderRegistration(P key, DataReader<P, D> instance) {
+ super(instance);
+ this.key = key;
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.core.api;
+
+import java.util.concurrent.Future;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface RpcConsumptionRegistry {
+ /**
+ * Sends an RPC to other components registered to the broker.
+ *
+ * @see RpcImplementation
+ * @param rpc
+ * Name of RPC
+ * @param input
+ * Input data to the RPC
+ * @return Result of the RPC call
+ */
+ Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input);
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.core.api;
+
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public interface RpcProvisionRegistry {
+
+ /**
+ * Registers an implementation of the rpc.
+ *
+ * <p>
+ * The registered rpc functionality will be available to all other
+ * consumers and providers registered to the broker, which are aware of
+ * the {@link QName} assigned to the rpc.
+ *
+ * <p>
+ * There is no assumption that rpc type is in the set returned by
+ * invoking {@link RpcImplementation#getSupportedRpcs()}. This allows
+ * for dynamic rpc implementations.
+ *
+ * @param rpcType
+ * Name of Rpc
+ * @param implementation
+ * Provider's Implementation of the RPC functionality
+ * @throws IllegalArgumentException
+ * If the name of RPC is invalid
+ */
+ RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException;
+
+ RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
+}
import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService;
import org.opendaylight.controller.sal.common.DataStoreIdentifier;
import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;;
public interface DataProviderService extends
DataBrokerService, //
*/
void removeRefresher(DataStoreIdentifier store, DataRefresher refresher);
+
+ Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader);
+
+ Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader);
+
public interface DataRefresher extends Provider.ProviderFunctionality {
/**
--- /dev/null
+package org.opendaylight.controller.sal.core.api.mount;
+
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+
+public interface MountProvisionInstance extends MountInstance, NotificationPublishService, RpcProvisionRegistry {
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.core.api.mount;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public interface MountProvisionService extends MountService {
+
+ @Override
+ public MountProvisionInstance getMountPoint(InstanceIdentifier path);
+
+ MountProvisionInstance createMountPoint(InstanceIdentifier path);
+
+ MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
+}
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>sal-common-util</artifactId>\r
<version>1.0-SNAPSHOT</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>sal-common-impl</artifactId>\r
+ <version>1.0-SNAPSHOT</version>\r
</dependency>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>\r
<Bundle-Activator>org.opendaylight.controller.sal.dom.broker.BrokerActivator</Bundle-Activator>\r
<Private-Package>\r
- org.opendaylight.controller.sal.dom.broker,\r
+ org.opendaylight.controller.sal.dom.broker.*\r
</Private-Package>\r
</instructions>\r
</configuration>\r
*/
package org.opendaylight.controller.sal.dom.broker;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.BrokerService;
-import org.opendaylight.controller.sal.core.api.Consumer;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.spi.BrokerModule;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.osgi.framework.BundleContext;
-import org.slf4j.LoggerFactory;
+import java.util.Collections
+import java.util.HashMap
+import java.util.HashSet
+import java.util.Map
+import java.util.Set
+import java.util.concurrent.Callable
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+import java.util.concurrent.Future
+import org.opendaylight.controller.sal.core.api.Broker
+import org.opendaylight.controller.sal.core.api.BrokerService
+import org.opendaylight.controller.sal.core.api.Consumer
+import org.opendaylight.controller.sal.core.api.Provider
+import org.opendaylight.controller.sal.core.spi.BrokerModule
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.osgi.framework.BundleContext
+import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter
import org.opendaylight.yangtools.concepts.ListenerRegistration
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
-import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry
public class BrokerImpl implements Broker {
private static val log = LoggerFactory.getLogger(BrokerImpl);
private val Map<Class<? extends BrokerService>, BrokerModule> serviceProviders = Collections.
synchronizedMap(new HashMap<Class<? extends BrokerService>, BrokerModule>());
-
- private val rpcRegistrationListeners = new ListenerRegistry<RpcRegistrationListener>();
- // RPC Context
- private val Map<QName, RpcImplementation> rpcImpls = Collections.synchronizedMap(
- new HashMap<QName, RpcImplementation>());
-
// Implementation specific
@Property
private var ExecutorService executor = Executors.newFixedThreadPool(5);
@Property
private var BundleContext bundleContext;
+
+ @Property
+ private var RpcRouter router;
override registerConsumer(Consumer consumer, BundleContext ctx) {
checkPredicates(consumer);
return prov.getServiceForSession(service, session);
}
- // RPC Functionality
- protected def void addRpcImplementation(QName rpcType, RpcImplementation implementation) {
- if(rpcImpls.get(rpcType) != null) {
- throw new IllegalStateException("Implementation for rpc " + rpcType + " is already registered.");
- }
-
-
- rpcImpls.put(rpcType, implementation);
-
-
- for(listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationAdded(rpcType);
- } catch (Exception e){
- log.error("Unhandled exception during invoking listener",e);
- }
- }
- }
-
- protected def void removeRpcImplementation(QName rpcType, RpcImplementation implToRemove) {
- if(implToRemove == rpcImpls.get(rpcType)) {
- rpcImpls.remove(rpcType);
- }
-
- for(listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationRemoved(rpcType);
- } catch (Exception e){
- log.error("Unhandled exception during invoking listener",e);
- }
- }
- }
-
protected def Future<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- val impl = rpcImpls.get(rpc);
- val result = executor.submit([|impl.invokeRpc(rpc, input)] as Callable<RpcResult<CompositeNode>>);
+ val result = executor.submit([|router.invokeRpc(rpc, input)] as Callable<RpcResult<CompositeNode>>);
return result;
}
sessions.remove(consumerContextImpl);
providerSessions.remove(consumerContextImpl);
}
-
- protected def getSupportedRpcs() {
- rpcImpls.keySet;
- }
-
- def ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
- rpcRegistrationListeners.register(listener);
- }
}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker;
+
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
+import org.opendaylight.controller.sal.dom.broker.impl.NotificationRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class MountPointImpl implements MountProvisionInstance {
+
+ final RpcRouter rpcs;
+ final DataReaderRouter dataReader;
+ final NotificationRouter notificationRouter;
+
+ public MountPointImpl(InstanceIdentifier path) {
+ rpcs = new RpcRouterImpl("");
+ dataReader = new DataReaderRouter();
+ notificationRouter = new NotificationRouterImpl();
+ }
+
+ @Override
+ public void publish(CompositeNode notification) {
+ notificationRouter.publish(notification);
+ }
+
+ @Override
+ public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+ return notificationRouter.addNotificationListener(notification, listener);
+ }
+
+ @Override
+ public CompositeNode readConfigurationData(InstanceIdentifier path) {
+ return dataReader.readConfigurationData(path);
+ }
+
+ @Override
+ public CompositeNode readOperationalData(InstanceIdentifier path) {
+ return dataReader.readOperationalData(path);
+ }
+
+ public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
+ InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+ return dataReader.registerOperationalReader(path, reader);
+ }
+
+ public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
+ InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+ return dataReader.registerConfigurationReader(path, reader);
+ }
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return rpcs.addRoutedRpcImplementation(rpcType, implementation);
+ }
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException {
+ return rpcs.addRpcImplementation(rpcType, implementation);
+ }
+
+ public Set<QName> getSupportedRpcs() {
+ return rpcs.getSupportedRpcs();
+ }
+
+
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ return rpcs.invokeRpc(rpc, input);
+ }
+
+ public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
+ return rpcs.addRpcRegistrationListener(listener);
+ }
+
+
+ @Override
+ public Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public DataModificationTransaction beginTransaction() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
+ DataChangeListener listener) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void sendNotification(CompositeNode notification) {
+ publish(notification);
+
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker
+
+
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import java.util.concurrent.ConcurrentMap
+import java.util.concurrent.ConcurrentHashMap
+import static com.google.common.base.Preconditions.*;
+
+class MountPointManagerImpl implements MountProvisionService {
+
+ ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
+
+ override createMountPoint(InstanceIdentifier path) {
+ checkState(!mounts.containsKey(path),"Mount already created");
+ val mount = new MountPointImpl(path);
+ mounts.put(path,mount);
+ }
+
+
+ override createOrGetMountPoint(InstanceIdentifier path) {
+ val mount = mounts.get(path);
+ if(mount === null) {
+ return createMountPoint(path)
+ }
+ return mount;
+ }
+
+
+ override getMountPoint(InstanceIdentifier path) {
+ mounts.get(path);
+ }
+
+
+}
package org.opendaylight.controller.sal.dom.broker
-import java.util.Collections
-import java.util.HashMap
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
import org.opendaylight.controller.sal.core.api.Provider
import org.opendaylight.controller.sal.core.api.RpcImplementation
import org.opendaylight.yangtools.yang.common.QName
import org.osgi.framework.BundleContext
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration
-import static java.util.Collections.*
-import java.util.Collections
-import java.util.HashMap
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
+import org.opendaylight.yangtools.concepts.Registration
+
+import java.util.Set
+import java.util.HashSet
class ProviderContextImpl extends ConsumerContextImpl implements ProviderSession {
@Property
private val Provider provider;
- private val rpcImpls = Collections.synchronizedMap(new HashMap<QName, RpcImplementation>());
+ private val Set<Registration<?>> registrations = new HashSet();
new(Provider provider, BundleContext ctx) {
super(null, ctx);
}
override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException {
- if (rpcType == null) {
- throw new IllegalArgumentException("rpcType must not be null");
- }
- if (implementation == null) {
- throw new IllegalArgumentException("Implementation must not be null");
- }
- broker.addRpcImplementation(rpcType, implementation);
- rpcImpls.put(rpcType, implementation);
-
- return new RpcRegistrationImpl(rpcType, implementation, this);
+ val origReg = broker.router.addRpcImplementation(rpcType, implementation);
+ val newReg = new RpcRegistrationWrapper(origReg);
+ registrations.add(newReg);
+ return newReg;
}
- def removeRpcImplementation(RpcRegistrationImpl implToRemove) throws IllegalArgumentException {
- val localImpl = rpcImpls.get(implToRemove.type);
- if (localImpl !== implToRemove.instance) {
- throw new IllegalStateException("Implementation was not registered in this session");
- }
- broker.removeRpcImplementation(implToRemove.type, localImpl);
- rpcImpls.remove(implToRemove.type);
+ protected def removeRpcImplementation(RpcRegistrationWrapper implToRemove) throws IllegalArgumentException {
+ registrations.remove(implToRemove);
}
-
+
override close() {
- removeAllRpcImlementations
- super.close
- }
-
- private def removeAllRpcImlementations() {
- if (!rpcImpls.empty) {
- for (entry : rpcImpls.entrySet) {
- broker.removeRpcImplementation(entry.key, entry.value);
- }
- rpcImpls.clear
+
+ for (reg : registrations) {
+ reg.close()
}
+ super.close
}
override addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) {
}
override getSupportedRpcs() {
- broker.getSupportedRpcs();
+ broker.router.supportedRpcs;
}
override addRpcRegistrationListener(RpcRegistrationListener listener) {
- broker.addRpcRegistrationListener(listener);
+ broker.router.addRpcRegistrationListener(listener);
}
}
-class RpcRegistrationImpl extends AbstractObjectRegistration<RpcImplementation> implements RpcRegistration {
+class RpcRegistrationWrapper implements RpcRegistration {
+
@Property
- val QName type
+ val RpcRegistration delegate
- private var ProviderContextImpl context
+ new(RpcRegistration delegate) {
+ _delegate = delegate
+ }
- new(QName type, RpcImplementation instance, ProviderContextImpl ctx) {
- super(instance)
- _type = type
- context = ctx
+ override getInstance() {
+ delegate.instance
}
- override protected removeRegistration() {
- context.removeRpcImplementation(this)
- context = null
+ override close() {
+ delegate.close
}
+ override getType() {
+ delegate.type
+ }
}
+
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.impl
+
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+
+class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
+
+ override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
+ return data.iterator.next
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.api.BrokerService;
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Consumer.ConsumerFunctionality;
+import org.opendaylight.controller.sal.core.api.Provider.ProviderFunctionality;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.controller.sal.core.api.notify.NotificationService;
+import org.opendaylight.controller.sal.core.spi.BrokerModule;
+import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+
+public class NotificationRouterImpl implements NotificationRouter {
+ private static Logger log = LoggerFactory.getLogger(NotificationRouterImpl.class);
+
+ private Multimap<QName, Registration<NotificationListener>> listeners = HashMultimap.create();
+
+ private void sendNotification(CompositeNode notification) {
+ QName type = notification.getNodeType();
+ Collection<Registration<NotificationListener>> toNotify = listeners.get(type);
+ log.info("Publishing notification " + type);
+
+ if (toNotify == null) {
+ // No listeners were registered - returns.
+ return;
+ }
+
+ for (Registration<NotificationListener> listener : toNotify) {
+ try {
+ // FIXME: ensure that notification is immutable
+ listener.getInstance().onNotification(notification);
+ } catch (Exception e) {
+ log.error("Uncaught exception in NotificationListener", e);
+ }
+ }
+
+ }
+
+ @Override
+ public void publish(CompositeNode notification) {
+ sendNotification(notification);
+ }
+
+ @Override
+ public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+ ListenerRegistration ret = new ListenerRegistration(notification, listener);
+ return ret;
+ }
+
+ private class ListenerRegistration extends AbstractObjectRegistration<NotificationListener> {
+
+ final QName type;
+
+ public ListenerRegistration(QName type, NotificationListener instance) {
+ super(instance);
+ this.type = type;
+ }
+
+ @Override
+ protected void removeRegistration() {
+ listeners.remove(type, this);
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.impl
+
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter
+import org.opendaylight.yangtools.concepts.Identifiable
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.controller.sal.core.api.RpcImplementation
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import static com.google.common.base.Preconditions.*;
+import java.util.Map
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration
+import java.util.concurrent.ConcurrentHashMap
+import java.util.Set
+import java.util.Collections
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
+import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
+import org.slf4j.LoggerFactory
+
+class RpcRouterImpl implements RpcRouter, Identifiable<String> {
+
+ static val log = LoggerFactory.getLogger(RpcRouterImpl)
+
+ Map<QName, RpcRegistration> implementations = new ConcurrentHashMap();
+
+ @Property
+ val Set<QName> supportedRpcs = Collections.unmodifiableSet(implementations.keySet);
+
+ private val rpcRegistrationListeners = new ListenerRegistry<RpcRegistrationListener>();
+
+ @Property
+ val String identifier;
+
+ new(String name) {
+ _identifier = name;
+ }
+
+ override addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ }
+
+ override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException {
+ checkNotNull(rpcType, "Rpc Type should not be null");
+ checkNotNull(implementation, "Implementation should not be null.");
+ checkState(!implementations.containsKey(rpcType), "Provider for supplied rpc is already registered.");
+ val reg = new RpcRegistrationImpl(rpcType, implementation, this);
+ implementations.put(rpcType, reg)
+
+ for (listener : rpcRegistrationListeners.listeners) {
+ try {
+ listener.instance.onRpcImplementationAdded(rpcType);
+ } catch (Exception e) {
+ log.error("Unhandled exception during invoking listener", e);
+ }
+ }
+
+ return reg;
+
+ }
+
+ override invokeRpc(QName rpc, CompositeNode input) {
+ checkNotNull(rpc, "Rpc Type should not be null");
+
+ val impl = implementations.get(rpc);
+ checkState(impl !== null, "Provider for supplied rpc is not registered.");
+
+ return impl.instance.invokeRpc(rpc, input);
+ }
+
+ def remove(RpcRegistrationImpl impl) {
+ val existing = implementations.get(impl.type);
+ if (existing == impl) {
+ implementations.remove(impl.type);
+ }
+ for (listener : rpcRegistrationListeners.listeners) {
+ try {
+ listener.instance.onRpcImplementationRemoved(impl.type);
+ } catch (Exception e) {
+ log.error("Unhandled exception during invoking listener", e);
+ }
+ }
+ }
+
+ override addRpcRegistrationListener(RpcRegistrationListener listener) {
+ rpcRegistrationListeners.register(listener);
+ }
+
+}
+
+class RpcRegistrationImpl extends AbstractObjectRegistration<RpcImplementation> implements RpcRegistration {
+
+ @Property
+ val QName type;
+
+ @Property
+ var RpcRouterImpl router;
+
+ new(QName type, RpcImplementation instance, RpcRouterImpl router) {
+ super(instance)
+ _type = type
+ _router = router
+ }
+
+ override protected removeRegistration() {
+ router.remove(this);
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.spi;
+
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface NotificationRouter {
+
+ void publish(CompositeNode notification);
+
+ /**
+ * Registers a notification listener for supplied notification type.
+ *
+ * @param notification
+ * @param listener
+ */
+ Registration<NotificationListener> addNotificationListener(QName notification,
+ NotificationListener listener);
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.spi;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public interface RoutedRpcProcessor extends RpcImplementation {
+
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
+
+ public Set<QName> getSupportedRpcs();
+
+ public QName getRpcType();
+
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
+
+ Map<InstanceIdentifier,RpcImplementation> getRoutes();
+
+ RpcImplementation getDefaultRoute();
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.spi;
+
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface RpcRouter extends RpcProvisionRegistry, RpcImplementation {
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException;
+
+ @Override
+ public Set<QName> getSupportedRpcs();
+
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
+
+ ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener);
+}
<artifactId>sal-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
+ <properties>
+ <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+ </properties>
<artifactId>sal-netconf-connector</artifactId>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<groupId>${project.groupId}</groupId>
<artifactId>sal-connector-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sal-common-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-client</artifactId>
+ <version>0.2.2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-impl</artifactId>
+ <version>0.5.9-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-test</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-api</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-util</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-store-api</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-api</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>util</artifactId>
+ <scope>test</scope>
+ <version>0.3.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-client</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-netconf-connector</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-test</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-manager</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-impl</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-manager</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-impl</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-mapping-api</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-util</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-store-impl</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-store-impl</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>logback-config</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
</dependencies>
<packaging>bundle</packaging>
<artifactId>netty-handler</artifactId>
<version>${netconf.netty.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ </dependency>
</dependencies>
<build>
org.opendaylight.controller.config.stat,
com.google.common.base,
com.google.common.collect,
+ ch.ethz.ssh2,
io.netty.buffer,
io.netty.channel,
io.netty.channel.socket,
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh;
+
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import java.io.IOException;
+import java.net.SocketAddress;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.Invoker;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.SshClient;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.SshClientAdapter;
+import org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket.VirtualSocket;
+
+/**
+ * Netty SSH handler class. Acts as interface between Netty and SSH library. All standard Netty message handling
+ * stops at instance of this class. All downstream events are handed of to wrapped {@link org.opendaylight.controller.netconf.util.handler.ssh.client.SshClientAdapter};
+ */
+public class SshHandler extends ChannelOutboundHandlerAdapter {
+ private final VirtualSocket virtualSocket = new VirtualSocket();
+ private final SshClientAdapter sshClientAdapter;
+
+ public SshHandler(AuthenticationHandler authenticationHandler, Invoker invoker) throws IOException {
+ SshClient sshClient = new SshClient(virtualSocket, authenticationHandler);
+ this.sshClientAdapter = new SshClientAdapter(sshClient, invoker);
+ }
+
+ @Override
+ public void handlerAdded(ChannelHandlerContext ctx){
+ if (ctx.channel().pipeline().get("socket") == null) {
+ ctx.channel().pipeline().addFirst("socket", virtualSocket);
+ }
+ }
+
+ @Override
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+ if (ctx.channel().pipeline().get("socket") != null) {
+ ctx.channel().pipeline().remove("socket");
+ }
+ }
+
+ @Override
+ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
+ this.sshClientAdapter.write((String) msg);
+ }
+
+ @Override
+ public void connect(final ChannelHandlerContext ctx,
+ SocketAddress remoteAddress,
+ SocketAddress localAddress,
+ ChannelPromise promise) throws Exception {
+ ctx.connect(remoteAddress, localAddress, promise);
+
+ promise.addListener(new ChannelFutureListener() {
+ public void operationComplete(ChannelFuture channelFuture) throws Exception {
+ sshClientAdapter.start(ctx);
+ }}
+ );
+ }
+
+ @Override
+ public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
+ sshClientAdapter.stop(promise);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.authentication;
+
+import ch.ethz.ssh2.Connection;
+
+import java.io.IOException;
+
+/**
+ * Class providing authentication facility to SSH handler.
+ */
+public abstract class AuthenticationHandler {
+ public abstract void authenticate(Connection connection) throws IOException;
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.authentication;
+
+import ch.ethz.ssh2.Connection;
+
+import java.io.IOException;
+
+/**
+ * Class Providing username/password authentication option to {@link org.opendaylight.controller.netconf.util.handler.ssh.SshHandler}
+ */
+public class LoginPassword extends AuthenticationHandler {
+ private final String username;
+ private final String password;
+
+ public LoginPassword(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ @Override
+ public void authenticate(Connection connection) throws IOException {
+ boolean isAuthenticated = connection.authenticateWithPassword(username, password);
+
+ if (isAuthenticated == false) throw new IOException("Authentication failed.");
+ }
+}
--- /dev/null
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import java.io.IOException;
+
+/**
+ * Abstract class providing mechanism of invoking various SSH level services.
+ * Class is not allowed to be extended, as it provides its own implementations via instance initiators.
+ */
+public abstract class Invoker {
+ private boolean invoked = false;
+
+ private Invoker(){}
+
+ protected boolean isInvoked() {
+ return invoked;
+ }
+
+ abstract void invoke(SshSession session) throws IOException;
+
+ /**
+ * Invoker implementation to invokes subsystem SSH service.
+ *
+ * @param subsystem
+ * @return
+ */
+ public static Invoker subsystem(final String subsystem) {
+ return new Invoker() {
+ @Override
+ void invoke(SshSession session) throws IOException {
+ if (isInvoked() == true) throw new IllegalStateException("Already invoked.");
+
+ session.startSubSystem(subsystem);
+ }
+ };
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.Session;
+import ch.ethz.ssh2.channel.Channel;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket.VirtualSocket;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Wrapper class around GANYMED SSH java library.
+ */
+public class SshClient {
+ private final VirtualSocket socket;
+ private final Map<Integer, SshSession> openSessions = new HashMap();
+ private final AuthenticationHandler authenticationHandler;
+ private Connection connection;
+
+ public SshClient(VirtualSocket socket,
+ AuthenticationHandler authenticationHandler) throws IOException {
+ this.socket = socket;
+ this.authenticationHandler = authenticationHandler;
+ }
+
+ public SshSession openSession() throws IOException {
+ if(connection == null) connect();
+
+ Session session = connection.openSession();
+ SshSession sshSession = new SshSession(session);
+ openSessions.put(openSessions.size(), sshSession);
+
+ return sshSession;
+ }
+
+ private void connect() throws IOException {
+ connection = new Connection(socket);
+ connection.connect();
+ authenticationHandler.authenticate(connection);
+ }
+
+ public void closeSession(SshSession session) {
+ if( session.getState() == Channel.STATE_OPEN
+ || session.getState() == Channel.STATE_OPENING) {
+ session.session.close();
+ }
+ }
+
+ public void close() {
+ for(SshSession session : openSessions.values()) closeSession(session);
+
+ openSessions.clear();
+
+ if(connection != null) connection.close();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket.VirtualSocketException;
+
+/**
+ * Worker thread class. Handles all downstream and upstream events in SSH Netty pipeline.
+ */
+public class SshClientAdapter implements Runnable {
+ private final SshClient sshClient;
+ private final Invoker invoker;
+
+ private SshSession session;
+ private InputStream stdOut;
+ private InputStream stdErr;
+ private OutputStream stdIn;
+
+ private ChannelHandlerContext ctx;
+ private ChannelPromise disconnectPromise;
+
+ private final AtomicBoolean stopRequested = new AtomicBoolean(false);
+
+ private final Object lock = new Object();
+
+ public SshClientAdapter(SshClient sshClient,
+ Invoker invoker) {
+ this.sshClient = sshClient;
+ this.invoker = invoker;
+ }
+
+ public void run() {
+ try {
+ session = sshClient.openSession();
+ invoker.invoke(session);
+
+ stdOut = session.getStdout();
+ stdErr = session.getStderr();
+
+ synchronized(lock) {
+ stdIn = session.getStdin();
+ }
+
+ while (stopRequested.get() == false) {
+ byte[] readBuff = new byte[1024];
+ int c = stdOut.read(readBuff);
+
+ byte[] tranBuff = new byte[c];
+ System.arraycopy(readBuff, 0, tranBuff, 0, c);
+
+ ByteBuf byteBuf = Unpooled.buffer(c);
+ byteBuf.writeBytes(tranBuff);
+ ctx.fireChannelRead(byteBuf);
+ }
+
+ } catch (VirtualSocketException e) {
+ // Netty closed connection prematurely.
+ // Just pass and move on.
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ sshClient.close();
+
+ synchronized (lock) {
+ if(disconnectPromise != null) ctx.disconnect(disconnectPromise);
+ }
+ }
+ }
+
+ // TODO: needs rework to match netconf framer API.
+ public void write(String message) throws IOException {
+ synchronized (lock) {
+ if (stdIn == null) throw new IllegalStateException("StdIn not available");
+ }
+ stdIn.write(message.getBytes());
+ stdIn.flush();
+ }
+
+ public void stop(ChannelPromise promise) {
+ synchronized (lock) {
+ stopRequested.set(true);
+ disconnectPromise = promise;
+ }
+ }
+
+ public void start(ChannelHandlerContext ctx) {
+ if(this.ctx != null) return; // context is already associated.
+
+ this.ctx = ctx;
+ new Thread(this).start();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import ch.ethz.ssh2.Session;
+import ch.ethz.ssh2.StreamGobbler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Wrapper class for proprietary SSH sessions implementations
+ */
+public class SshSession {
+ final Session session;
+
+ public SshSession(Session session) {
+ this.session = session;
+ }
+
+ public void execCommand(String cmd) throws IOException {
+ session.execCommand(cmd);
+ }
+
+ public void execCommand(String cmd, String charsetName) throws IOException {
+ session.execCommand(cmd, charsetName);
+ }
+
+ public void startShell() throws IOException {
+ session.startShell();
+ }
+
+ public void startSubSystem(String name) throws IOException {
+ session.startSubSystem(name);
+ }
+
+ public int getState() {
+ return session.getState();
+ }
+
+ public InputStream getStdout() {
+ return new StreamGobbler(session.getStdout());
+ }
+
+ public InputStream getStderr() {
+ return session.getStderr();
+ }
+
+ public OutputStream getStdin() {
+ return session.getStdin();
+ }
+
+ public int waitUntilDataAvailable(long timeout) throws IOException {
+ return session.waitUntilDataAvailable(timeout);
+ }
+
+ public int waitForCondition(int condition_set, long timeout) {
+ return session.waitForCondition(condition_set, timeout);
+ }
+
+ public Integer getExitStatus() {
+ return session.getExitStatus();
+ }
+
+ public String getExitSignal() {
+ return session.getExitSignal();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Class provides {@link InputStream} functionality to users of virtual socket.
+ */
+public class ChannelInputStream extends InputStream implements ChannelInboundHandler {
+ private final Object lock = new Object();
+ private final ByteBuf bb = Unpooled.buffer();
+
+ @Override
+ public int read(byte b[], int off, int len) throws IOException {
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || len < 0 || len > b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int bytesRead = 1;
+ synchronized (lock) {
+ int c = read();
+
+ b[off] = (byte)c;
+
+ if(this.bb.readableBytes() == 0) return bytesRead;
+
+ int ltr = len-1;
+ ltr = (ltr <= bb.readableBytes()) ? ltr : bb.readableBytes();
+
+ bb.readBytes(b, 1, ltr);
+ bytesRead += ltr;
+ }
+ return bytesRead;
+ }
+
+ @Override
+ public int read() throws IOException {
+ synchronized (lock) {
+ while (this.bb.readableBytes() == 0) {
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return this.bb.readByte() & 0xFF;
+ }
+ }
+
+ @Override
+ public int available() throws IOException {
+ synchronized (lock) {
+ return this.bb.readableBytes();
+ }
+ }
+
+ public void channelRegistered(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelRegistered();
+ }
+
+ public void channelUnregistered(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelUnregistered();
+ }
+
+ public void channelActive(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelActive();
+ }
+
+ public void channelInactive(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelInactive();
+ }
+
+ public void channelRead(ChannelHandlerContext ctx, Object o)
+ throws Exception {
+ synchronized(lock) {
+ this.bb.discardReadBytes();
+ this.bb.writeBytes((ByteBuf) o);
+ lock.notifyAll();
+ }
+ }
+
+ public void channelReadComplete(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelReadComplete();
+ }
+
+ public void userEventTriggered(ChannelHandlerContext ctx, Object o)
+ throws Exception {
+ ctx.fireUserEventTriggered(o);
+ }
+
+ public void channelWritabilityChanged(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.fireChannelWritabilityChanged();
+ }
+
+ public void handlerAdded(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void handlerRemoved(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable)
+ throws Exception {
+ ctx.fireExceptionCaught(throwable);
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandler;
+import io.netty.channel.ChannelPromise;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.SocketAddress;
+
+/**
+ * Class provides {@link OutputStream) functionality to users of virtual socket.
+ */
+public class ChannelOutputStream extends OutputStream implements ChannelOutboundHandler {
+ private final Object lock = new Object();
+ private ByteBuf buff = Unpooled.buffer();
+ private ChannelHandlerContext ctx;
+
+ @Override
+ public void flush() throws IOException {
+ synchronized(lock) {
+ ctx.writeAndFlush(buff).awaitUninterruptibly();
+ buff = Unpooled.buffer();
+ }
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ synchronized(lock) {
+ buff.writeByte(b);
+ }
+ }
+
+ public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,
+ ChannelPromise promise) throws Exception {
+ ctx.bind(localAddress, promise);
+ }
+
+ public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,
+ SocketAddress localAddress, ChannelPromise promise)
+ throws Exception {
+ this.ctx = ctx;
+ ctx.connect(remoteAddress, localAddress, promise);
+ }
+
+ public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
+ throws Exception {
+ ctx.disconnect(promise);
+ }
+
+ public void close(ChannelHandlerContext ctx, ChannelPromise promise)
+ throws Exception {
+ ctx.close(promise);
+ }
+
+ public void deregister(ChannelHandlerContext ctx, ChannelPromise channelPromise)
+ throws Exception {
+ ctx.deregister(channelPromise);
+ }
+
+ public void read(ChannelHandlerContext ctx)
+ throws Exception {
+ ctx.read();
+ }
+
+ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
+ throws Exception {
+ // pass
+ }
+
+ public void flush(ChannelHandlerContext ctx)
+ throws Exception {
+ // pass
+ }
+
+ public void handlerAdded(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void handlerRemoved(ChannelHandlerContext ctx)
+ throws Exception {
+ }
+
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
+ throws Exception {
+ ctx.fireExceptionCaught(cause);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SocketChannel;
+
+/**
+ * Handler class providing Socket functionality to OIO client application. By using VirtualSocket user can
+ * use OIO application in asynchronous environment and NIO EventLoop. Using VirtualSocket OIO applications
+ * are able to use full potential of NIO environment.
+ */
+public class VirtualSocket extends Socket implements ChannelHandler {
+ private final ChannelInputStream chis = new ChannelInputStream();
+ private final ChannelOutputStream chos = new ChannelOutputStream();
+ private ChannelHandlerContext ctx;
+
+
+ public InputStream getInputStream() {
+ return this.chis;
+ }
+
+ public OutputStream getOutputStream() {
+ return this.chos;
+ }
+
+ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
+ this.ctx = ctx;
+
+ if (ctx.channel().pipeline().get("outputStream") == null) {
+ ctx.channel().pipeline().addFirst("outputStream", chos);
+ }
+
+ if (ctx.channel().pipeline().get("inputStream") == null) {
+ ctx.channel().pipeline().addFirst("inputStream", chis);
+ }
+ }
+
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+ if (ctx.channel().pipeline().get("outputStream") != null) {
+ ctx.channel().pipeline().remove("outputStream");
+ }
+
+ if (ctx.channel().pipeline().get("inputStream") != null) {
+ ctx.channel().pipeline().remove("inputStream");
+ }
+ }
+
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) throws Exception {
+ ctx.fireExceptionCaught(throwable);
+ }
+
+ public VirtualSocket() {super();}
+
+ @Override
+ public void connect(SocketAddress endpoint) throws IOException {}
+
+ @Override
+ public void connect(SocketAddress endpoint, int timeout) throws IOException {}
+
+ @Override
+ public void bind(SocketAddress bindpoint) throws IOException {}
+
+ @Override
+ public InetAddress getInetAddress() {
+ InetSocketAddress isa = getInetSocketAddress();
+
+ if (isa == null) throw new VirtualSocketException();
+
+ return getInetSocketAddress().getAddress();
+ }
+
+ @Override
+ public InetAddress getLocalAddress() {return null;}
+
+ @Override
+ public int getPort() {
+ return getInetSocketAddress().getPort();
+ }
+
+ private InetSocketAddress getInetSocketAddress() {
+ return (InetSocketAddress)getRemoteSocketAddress();
+ }
+
+ @Override
+ public int getLocalPort() {return -1;}
+
+ @Override
+ public SocketAddress getRemoteSocketAddress() {
+ return this.ctx.channel().remoteAddress();
+ }
+
+ @Override
+ public SocketAddress getLocalSocketAddress() {
+ return this.ctx.channel().localAddress();
+ }
+
+ @Override
+ public SocketChannel getChannel() {return null;}
+
+ @Override
+ public void setTcpNoDelay(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getTcpNoDelay() throws SocketException {return false;}
+
+ @Override
+ public void setSoLinger(boolean on, int linger) throws SocketException {}
+
+ @Override
+ public int getSoLinger() throws SocketException {return -1;}
+
+ @Override
+ public void sendUrgentData(int data) throws IOException {}
+
+ @Override
+ public void setOOBInline(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getOOBInline() throws SocketException {return false;}
+
+ @Override
+ public synchronized void setSoTimeout(int timeout) throws SocketException {}
+
+ @Override
+ public synchronized int getSoTimeout() throws SocketException {return -1;}
+
+ @Override
+ public synchronized void setSendBufferSize(int size) throws SocketException {}
+
+ @Override
+ public synchronized int getSendBufferSize() throws SocketException {return -1;}
+
+ @Override
+ public synchronized void setReceiveBufferSize(int size) throws SocketException {}
+
+ @Override
+ public synchronized int getReceiveBufferSize() throws SocketException {return -1;}
+
+ @Override
+ public void setKeepAlive(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getKeepAlive() throws SocketException {return false;}
+
+ @Override
+ public void setTrafficClass(int tc) throws SocketException {}
+
+ @Override
+ public int getTrafficClass() throws SocketException {return -1;}
+
+ @Override
+ public void setReuseAddress(boolean on) throws SocketException {}
+
+ @Override
+ public boolean getReuseAddress() throws SocketException {return false;}
+
+ @Override
+ public synchronized void close() throws IOException {}
+
+ @Override
+ public void shutdownInput() throws IOException {}
+
+ @Override
+ public void shutdownOutput() throws IOException {}
+
+ @Override
+ public String toString() {
+ return "Virtual socket InetAdress["+getInetAddress()+"], Port["+getPort()+"]";
+ }
+
+ @Override
+ public boolean isConnected() {return false;}
+
+ @Override
+ public boolean isBound() {return false;}
+
+ @Override
+ public boolean isClosed() {return false;}
+
+ @Override
+ public boolean isInputShutdown() {return false;}
+
+ @Override
+ public boolean isOutputShutdown() {return false;}
+
+ @Override
+ public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {}
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are 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
+ */
+
+package org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket;
+
+/**
+ * Exception class which provides notification about exceptional situations at the virtual socket layer.
+ */
+public class VirtualSocketException extends RuntimeException {
+}
<module>config-persister-impl</module>
<module>netconf-mapping-api</module>
<module>netconf-client</module>
+ <module>../../third-party/ganymed</module>
</modules>
<profiles>
}\r
\r
public boolean isEnableDHCP() {\r
- if (enableDHCP == null)\r
+ if (enableDHCP == null) {\r
return true;\r
+ }\r
return enableDHCP;\r
}\r
\r
public Boolean getEnableDHCP() { return enableDHCP; }\r
\r
public void setEnableDHCP(Boolean newValue) {\r
- this.enableDHCP = newValue;\r
+ enableDHCP = newValue;\r
}\r
\r
public String getTenantID() {\r
Iterator<String> i = fields.iterator();\r
while (i.hasNext()) {\r
String s = i.next();\r
- if (s.equals("id"))\r
+ if (s.equals("id")) {\r
ans.setSubnetUUID(this.getSubnetUUID());\r
- if (s.equals("network_id"))\r
+ }\r
+ if (s.equals("network_id")) {\r
ans.setNetworkUUID(this.getNetworkUUID());\r
- if (s.equals("name"))\r
+ }\r
+ if (s.equals("name")) {\r
ans.setName(this.getName());\r
- if (s.equals("ip_version"))\r
+ }\r
+ if (s.equals("ip_version")) {\r
ans.setIpVersion(this.getIpVersion());\r
- if (s.equals("cidr"))\r
+ }\r
+ if (s.equals("cidr")) {\r
ans.setCidr(this.getCidr());\r
- if (s.equals("gateway_ip"))\r
+ }\r
+ if (s.equals("gateway_ip")) {\r
ans.setGatewayIP(this.getGatewayIP());\r
+ }\r
if (s.equals("dns_nameservers")) {\r
List<String> nsList = new ArrayList<String>();\r
nsList.addAll(this.getDnsNameservers());\r
hRoutes.addAll(this.getHostRoutes());\r
ans.setHostRoutes(hRoutes);\r
}\r
- if (s.equals("enable_dhcp"))\r
+ if (s.equals("enable_dhcp")) {\r
ans.setEnableDHCP(this.getEnableDHCP());\r
- if (s.equals("tenant_id"))\r
+ }\r
+ if (s.equals("tenant_id")) {\r
ans.setTenantID(this.getTenantID());\r
+ }\r
}\r
return ans;\r
}\r
try {\r
SubnetUtils util = new SubnetUtils(cidr);\r
SubnetInfo info = util.getInfo();\r
- if (!info.getNetworkAddress().equals(info.getAddress()))\r
+ if (!info.getNetworkAddress().equals(info.getAddress())) {\r
return false;\r
+ }\r
} catch (Exception e) {\r
return false;\r
}\r
Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
while (i.hasNext()) {\r
NeutronSubnet_IPAllocationPool pool = i.next();\r
- if (pool.contains(gatewayIP))\r
+ if (pool.contains(gatewayIP)) {\r
return true;\r
+ }\r
}\r
return false;\r
}\r
\r
- public void initDefaults() {\r
- if (enableDHCP == null)\r
+ public boolean initDefaults() {\r
+ if (enableDHCP == null) {\r
enableDHCP = true;\r
- if (ipVersion == null)\r
+ }\r
+ if (ipVersion == null) {\r
ipVersion = 4;\r
+ }\r
gatewayIPAssigned = false;\r
dnsNameservers = new ArrayList<String>();\r
allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
try {\r
SubnetUtils util = new SubnetUtils(cidr);\r
SubnetInfo info = util.getInfo();\r
- if (gatewayIP == null)\r
+ if (gatewayIP == null) {\r
gatewayIP = info.getLowAddress();\r
+ }\r
if (allocationPools.size() < 1) {\r
NeutronSubnet_IPAllocationPool source =\r
new NeutronSubnet_IPAllocationPool(info.getLowAddress(),\r
allocationPools = source.splitPool(gatewayIP);\r
}\r
} catch (Exception e) {\r
+ return false;\r
}\r
+ return true;\r
}\r
\r
public List<NeutronPort> getPortsInSubnet() {\r
* available allocation pools or not\r
*/\r
public boolean isIPInUse(String ipAddress) {\r
- if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned )\r
+ if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned ) {\r
return false;\r
+ }\r
Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
while (i.hasNext()) {\r
NeutronSubnet_IPAllocationPool pool = i.next();\r
- if (pool.contains(ipAddress))\r
+ if (pool.contains(ipAddress)) {\r
return false;\r
+ }\r
}\r
return true;\r
}\r
}\r
else\r
if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <\r
- NeutronSubnet_IPAllocationPool.convert(ans))\r
+ NeutronSubnet_IPAllocationPool.convert(ans)) {\r
ans = pool.getPoolStart();\r
+ }\r
}\r
return ans;\r
}\r
if (pool.contains(ipAddress)) {\r
List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);\r
newList.addAll(pools);\r
- } else\r
+ } else {\r
newList.add(pool);\r
+ }\r
}\r
}\r
allocationPools = newList;\r
NeutronSubnet_IPAllocationPool pool = i.next();\r
long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());\r
long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());\r
- if (sIP+1 == lIP)\r
+ if (sIP+1 == lIP) {\r
hPool = pool;\r
- if (sIP-1 == hIP)\r
+ }\r
+ if (sIP-1 == hIP) {\r
lPool = pool;\r
+ }\r
}\r
//if (lPool == NULL and hPool == NULL) create new pool where low = ip = high\r
- if (lPool == null && hPool == null)\r
+ if (lPool == null && hPool == null) {\r
allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));\r
+ }\r
//if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr\r
- if (lPool == null && hPool != null)\r
+ if (lPool == null && hPool != null) {\r
hPool.setPoolStart(ipAddress);\r
+ }\r
//if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr\r
- if (lPool != null && hPool == null)\r
+ if (lPool != null && hPool == null) {\r
lPool.setPoolEnd(ipAddress);\r
+ }\r
//if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool\r
// where low address = lPool.low address and high address = hPool.high Address\r
if (lPool != null && hPool != null) {\r
import java.util.Map;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
* @param nodeId Node Identifier of the node with the management session.
* @param bridgeName Name / Identifier for a bridge to be created.
* @param bridgeConfigs Additional Bridge Configurations.
+ * It takes in complex structures under the ConfigConstants.CUSTOM key.
+ * The use-cases are documented under wiki.opendaylight.org project pages:
+ * https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial
*/
@Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
throw new ResourceNotFoundException(status.getDescription());
}
+
+ /**
+ * Remove a Bridge.
+ * <pre>
+ *
+ * Example :
+ *
+ * Request :
+ * DELETE
+ * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/bridge/STUB/mgmt1/bridge1
+ *
+ *</pre>
+ * @param nodeType Node Type of the node with the management session.
+ * @param nodeId Node Identifier of the node with the management session.
+ * @param bridgeName Name / Identifier for a bridge to be deleted.
+ */
+
+ @Path("/bridge/{nodeType}/{nodeId}/{bridgeName}")
+ @DELETE
+ @StatusCodes( { @ResponseCode(code = 200, condition = "Bridge deleted successfully"),
+ @ResponseCode(code = 404, condition = "Could not delete Bridge"),
+ @ResponseCode(code = 412, condition = "Failed to delete Bridge due to an exception"),
+ @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
+
+ public Response deleteBridge(
+ @PathParam(value = "nodeType") String nodeType,
+ @PathParam(value = "nodeId") String nodeId,
+ @PathParam(value = "bridgeName") String name) {
+
+ IBridgeDomainConfigService configurationService = getConfigurationService();
+ if (configurationService == null) {
+ throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
+ }
+
+ Node node = Node.fromString(nodeType, nodeId);
+ Status status = null;
+ try {
+ status = configurationService.deleteBridgeDomain(node, name);
+ if (status.getCode().equals(StatusCode.SUCCESS)) {
+ return Response.status(Response.Status.OK).build();
+ }
+ } catch (Throwable t) {
+ return Response.status(Response.Status.PRECONDITION_FAILED).build();
+ }
+ throw new ResourceNotFoundException(status.getDescription());
+ }
+
/**
* Add a Port to a Bridge
* <pre>
* @param bridgeName Name / Identifier of the bridge to which a Port is being added.
* @param portName Name / Identifier of a Port that is being added to a bridge.
* @param portConfigs Additional Port Configurations.
+ * It takes in complex structures under the ConfigConstants.CUSTOM key.
+ * The use-cases are documented under wiki.opendaylight.org project pages :
+ * https://wiki.opendaylight.org/view/OVSDB_Integration:Mininet_OVSDB_Tutorial
*/
@Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
throw new ResourceNotFoundException(status.getDescription());
}
+ /**
+ * Remove a Port from a Bridge
+ * <pre>
+ *
+ * Example :
+ *
+ * Request :
+ * DELETE
+ * http://localhost:8080/controller/nb/v2/networkconfig/bridgedomain/port/STUB/mgmt1/bridge1/port1
+ *
+ *</pre>
+ * @param nodeType Node Type of the node with the management session.
+ * @param nodeId Node Identifier of the node with the management session.
+ * @param bridgeName Name / Identifier of the bridge to which a Port is being added.
+ * @param portName Name / Identifier of a Port that is being deleted from a bridge.
+ */
+
+ @Path("/port/{nodeType}/{nodeId}/{bridgeName}/{portName}")
+ @DELETE
+ @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+ @StatusCodes( { @ResponseCode(code = 200, condition = "Port deleted successfully"),
+ @ResponseCode(code = 404, condition = "Could not delete Port to the Bridge"),
+ @ResponseCode(code = 412, condition = "Failed to delete Port due to an exception"),
+ @ResponseCode(code = 503, condition = "Bridge Domain Configuration Service not available")} )
+
+ public Response deletePort(
+ @PathParam(value = "nodeType") String nodeType,
+ @PathParam(value = "nodeId") String nodeId,
+ @PathParam(value = "bridgeName") String bridge,
+ @PathParam(value = "portName") String port) {
+
+ IBridgeDomainConfigService configurationService = getConfigurationService();
+ if (configurationService == null) {
+ throw new ServiceUnavailableException("IBridgeDomainConfigService not available.");
+ }
+
+ Node node = Node.fromString(nodeType, nodeId);
+ Status status = null;
+ try {
+ status = configurationService.deletePort(node, bridge, port);
+ if (status.getCode().equals(StatusCode.SUCCESS)) {
+ return Response.status(Response.Status.OK).build();
+ }
+ } catch (Throwable t) {
+ return Response.status(Response.Status.PRECONDITION_FAILED).build();
+ }
+ throw new ResourceNotFoundException(status.getDescription());
+ }
+
private Map<ConfigConstants, Object> buildConfig(Map<String, Object> rawConfigs) {
if (rawConfigs == null) return null;
Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
- <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
+ <param-value>GET,POST,DELETE,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;\r
import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
import org.opendaylight.controller.sal.utils.ServiceHelper;\r
\r
(queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&\r
(queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&\r
(queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
- if (fields.size() > 0)\r
+ if (fields.size() > 0) {\r
ans.add(extractFields(oSS,fields));\r
- else\r
+ } else {\r
ans.add(oSS);\r
+ }\r
}\r
}\r
//TODO: apply pagination to results\r
throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+ RestMessages.SERVICEUNAVAILABLE.toString());\r
}\r
- if (!subnetInterface.subnetExists(subnetUUID))\r
+ if (!subnetInterface.subnetExists(subnetUUID)) {\r
return Response.status(404).build();\r
+ }\r
if (fields.size() > 0) {\r
NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);\r
return Response.status(200).entity(\r
new NeutronSubnetRequest(extractFields(ans, fields))).build();\r
- } else\r
+ } else {\r
return Response.status(200).entity(\r
new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
+ }\r
}\r
\r
/**\r
* and that the gateway IP doesn't overlap with the allocation pools\r
* *then* add the subnet to the cache\r
*/\r
- if (subnetInterface.subnetExists(singleton.getID()))\r
+ if (subnetInterface.subnetExists(singleton.getID())) {\r
return Response.status(400).build();\r
- if (!networkInterface.networkExists(singleton.getNetworkUUID()))\r
+ }\r
+ if (!networkInterface.networkExists(singleton.getNetworkUUID())) {\r
return Response.status(404).build();\r
- if (!singleton.isValidCIDR())\r
+ }\r
+ if (!singleton.isValidCIDR()) {\r
return Response.status(400).build();\r
- singleton.initDefaults();\r
- if (singleton.gatewayIP_Pool_overlap())\r
+ }\r
+ if (!singleton.initDefaults()) {\r
+ throw new InternalServerErrorException("subnet object could not be initialized properly");\r
+ }\r
+ if (singleton.gatewayIP_Pool_overlap()) {\r
return Response.status(409).build();\r
+ }\r
Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canCreateSubnet(singleton);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
subnetInterface.addSubnet(singleton);\r
* and that the bulk request doesn't already contain a subnet with this id\r
*/\r
\r
- test.initDefaults();\r
- if (subnetInterface.subnetExists(test.getID()))\r
+ if (!test.initDefaults()) {\r
+ throw new InternalServerErrorException("subnet object could not be initialized properly");\r
+ }\r
+ if (subnetInterface.subnetExists(test.getID())) {\r
return Response.status(400).build();\r
- if (testMap.containsKey(test.getID()))\r
+ }\r
+ if (testMap.containsKey(test.getID())) {\r
return Response.status(400).build();\r
+ }\r
testMap.put(test.getID(), test);\r
- if (!networkInterface.networkExists(test.getNetworkUUID()))\r
+ if (!networkInterface.networkExists(test.getNetworkUUID())) {\r
return Response.status(404).build();\r
- if (!test.isValidCIDR())\r
+ }\r
+ if (!test.isValidCIDR()) {\r
return Response.status(400).build();\r
- if (test.gatewayIP_Pool_overlap())\r
+ }\r
+ if (test.gatewayIP_Pool_overlap()) {\r
return Response.status(409).build();\r
+ }\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canCreateSubnet(test);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
}\r
/*\r
* verify the subnet exists and there is only one delta provided\r
*/\r
- if (!subnetInterface.subnetExists(subnetUUID))\r
+ if (!subnetInterface.subnetExists(subnetUUID)) {\r
return Response.status(404).build();\r
- if (!input.isSingleton())\r
+ }\r
+ if (!input.isSingleton()) {\r
return Response.status(400).build();\r
+ }\r
NeutronSubnet delta = input.getSingleton();\r
NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);\r
\r
*/\r
if (delta.getID() != null || delta.getTenantID() != null ||\r
delta.getIpVersion() != null || delta.getCidr() != null ||\r
- delta.getAllocationPools() != null)\r
+ delta.getAllocationPools() != null) {\r
return Response.status(400).build();\r
+ }\r
\r
Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canUpdateSubnet(delta, original);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
\r
/*\r
* verify the subnet exists and it isn't currently in use\r
*/\r
- if (!subnetInterface.subnetExists(subnetUUID))\r
+ if (!subnetInterface.subnetExists(subnetUUID)) {\r
return Response.status(404).build();\r
- if (subnetInterface.subnetInUse(subnetUUID))\r
+ }\r
+ if (subnetInterface.subnetInUse(subnetUUID)) {\r
return Response.status(409).build();\r
+ }\r
NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);\r
Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
if (instances != null) {\r
for (Object instance : instances) {\r
INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
int status = service.canDeleteSubnet(singleton);\r
- if (status < 200 || status > 299)\r
+ if (status < 200 || status > 299) {\r
return Response.status(status).build();\r
+ }\r
}\r
}\r
\r
org.opendaylight.controller.forwardingrulesmanager,
org.opendaylight.controller.sal.authorization,
org.opendaylight.controller.sal.action,
+ org.opendaylight.controller.sal.connection,
org.opendaylight.controller.sal.core,
org.opendaylight.controller.sal.utils,
org.opendaylight.controller.containermanager,
+ org.opendaylight.controller.connectionmanager,
org.opendaylight.controller.switchmanager,
org.opendaylight.controller.forwarding.staticrouting,
org.opendaylight.controller.usermanager,
<artifactId>forwardingrulesmanager</artifactId>
<version>0.4.1-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>connectionmanager</artifactId>
+ <version>0.1.1-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
+import org.opendaylight.controller.connectionmanager.IConnectionManager;
import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
import org.opendaylight.controller.sal.authorization.Privilege;
import org.opendaylight.controller.sal.authorization.UserLevel;
+import org.opendaylight.controller.sal.connection.ConnectionConstants;
import org.opendaylight.controller.sal.core.Config;
import org.opendaylight.controller.sal.core.Description;
import org.opendaylight.controller.sal.core.ForwardingMode;
import org.opendaylight.controller.sal.core.Tier;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.NetUtils;
import org.opendaylight.controller.sal.utils.ServiceHelper;
import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.utils.TierHelper;
import org.opendaylight.controller.switchmanager.ISwitchManager;
import org.opendaylight.controller.switchmanager.SpanConfig;
import org.opendaylight.controller.web.DaylightWebUtil;
import org.opendaylight.controller.web.IDaylightWeb;
import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
return resultBean;
}
+ @RequestMapping(value = "/connect/nodes", method = RequestMethod.GET)
+ @ResponseBody
+ public List<NodeJsonBean> getNodes(HttpServletRequest request) {
+ IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
+ IConnectionManager.class, this);
+ if (connectionManager == null) {
+ return null;
+ }
+ ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+ GlobalConstants.DEFAULT.toString(), this);
+ if (switchManager == null) {
+ return null;
+ }
+
+ Set<Node> nodes = connectionManager.getLocalNodes();
+ List<NodeJsonBean> result = new LinkedList<NodeJsonBean>();
+ if (nodes == null) {
+ return result;
+ }
+ for (Node node : nodes) {
+ Description descriptionProperty = (Description) switchManager.getNodeProp(node, "description");
+ String description = node.toString();
+ if (descriptionProperty != null) {
+ description = descriptionProperty.getValue();
+ }
+ NodeJsonBean nodeBean = new NodeJsonBean();
+ nodeBean.setNodeId(node.getNodeIDString());
+ nodeBean.setNodeType(node.getType());
+ if (description.equals("None")) {
+ nodeBean.setNodeName(node.toString());
+ } else {
+ nodeBean.setNodeName(description);
+ }
+ result.add(nodeBean);
+ }
+
+ return result;
+ }
+
+ @RequestMapping(value = "/connect/{nodeId}", method = RequestMethod.POST)
+ @ResponseBody
+ public Status addNode(HttpServletRequest request, @PathVariable("nodeId") String nodeId,
+ @RequestParam(required = true) String ipAddress, @RequestParam(required = true) String port,
+ @RequestParam(required = false) String nodeType) {
+ IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
+ IConnectionManager.class, this);
+ if (connectionManager == null) {
+ return new Status(StatusCode.NOTFOUND, "Service not found");
+ }
+
+ if (!NetUtils.isIPv4AddressValid(ipAddress)) {
+ return new Status(StatusCode.NOTACCEPTABLE, "Invalid IP Address: " + ipAddress);
+ }
+
+ try {
+ Integer.parseInt(port);
+ } catch (Exception e) {
+ return new Status(StatusCode.NOTACCEPTABLE, "Invalid Layer 4 Port: " + port);
+ }
+
+ Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
+ params.put(ConnectionConstants.ADDRESS, ipAddress);
+ params.put(ConnectionConstants.PORT, port);
+
+ Node node = null;
+ if (nodeType != null) {
+ node = connectionManager.connect(nodeType, nodeId, params);
+ } else {
+ node = connectionManager.connect(nodeId, params);
+ }
+ if (node == null) {
+ return new Status(StatusCode.NOTFOUND, "Failed to connect to Node at " + ipAddress + ":" + port);
+ }
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ @RequestMapping(value = "/disconnect/{nodeId}", method = RequestMethod.POST)
+ @ResponseBody
+ public Status removeNode(HttpServletRequest request, @PathVariable("nodeId") String nodeId,
+ @RequestParam(required = true) String nodeType) {
+ IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
+ IConnectionManager.class, this);
+ if (connectionManager == null) {
+ return new Status(StatusCode.NOTFOUND, "Service not found");
+ }
+
+ try {
+ Node node = new Node(nodeType, nodeId);
+ return connectionManager.disconnect(node);
+ } catch (Exception e) {
+ return new Status(StatusCode.NOTFOUND, "Resource not found");
+ }
+ }
+
private String getNodeDesc(String nodeId, String containerName) {
ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
this);
return "forward:" + "/";
}
-}
\ No newline at end of file
+}
public class NodeJsonBean {
String nodeId;
String nodeName;
+ String nodeType;
List<PortJsonBean> nodePorts;
public String getNodeId() {
return nodeName;
}
+ public String getNodeType() {
+ return nodeType;
+ }
+
public List<PortJsonBean> getNodePorts() {
return nodePorts;
}
this.nodeName = nodeName;
}
+ public void setNodeType(String nodeType) {
+ this.nodeType = nodeType;
+ }
+
public void setNodePorts(List<PortJsonBean> port) {
this.nodePorts = port;
}
// specify dashlets and layouts
one.f.dashlet = {
- nodesLearnt : {
- id : 'nodesLearnt',
- name : 'Nodes Learned'
- },
- staticRouteConfig : {
- id : 'staticRouteConfig',
- name : 'Static Route Configuration'
- },
- subnetGatewayConfig : {
- id : 'subnetGatewayConfig',
- name : 'Subnet Gateway Configuration'
- },
- spanPortConfig : {
- id : 'spanPortConfig',
- name : 'SPAN Port Configuration'
- }
+ nodesLearnt : {
+ id : 'nodesLearnt',
+ name : 'Nodes Learned'
+ },
+ staticRouteConfig : {
+ id : 'staticRouteConfig',
+ name : 'Static Route Configuration'
+ },
+ subnetGatewayConfig : {
+ id : 'subnetGatewayConfig',
+ name : 'Subnet Gateway Configuration'
+ },
+ spanPortConfig : {
+ id : 'spanPortConfig',
+ name : 'SPAN Port Configuration'
+ },
+ connection : {
+ id : 'connection',
+ name : 'Connection Manager'
+ }
};
one.f.menu = {
- left : {
- top : [
- one.f.dashlet.nodesLearnt
- ],
- bottom : [
- one.f.dashlet.staticRouteConfig
- ]
- },
- right : {
- top : [],
- bottom : [
- one.f.dashlet.subnetGatewayConfig,
- one.f.dashlet.spanPortConfig
- ]
- }
+ left : {
+ top : [
+ one.f.dashlet.nodesLearnt,
+ one.f.dashlet.connection
+ ],
+ bottom : [
+ one.f.dashlet.staticRouteConfig
+ ]
+ },
+ right : {
+ top : [],
+ bottom : [
+ one.f.dashlet.subnetGatewayConfig,
+ one.f.dashlet.spanPortConfig
+ ]
+ }
};
/**Devices Modules */
one.f.switchmanager = {
- rootUrl: "controller/web/devices",
- createTable: function(columnNames, body) {
- var tableAttributes = ["table-striped", "table-bordered", "table-condensed"];
- var $table = one.lib.dashlet.table.table(tableAttributes);
- var tableHeaders = columnNames;
- var $thead = one.lib.dashlet.table.header(tableHeaders);
- var $tbody = one.lib.dashlet.table.body(body, tableHeaders);
- $table.append($thead)
- .append($tbody);
- return $table;
- },
- validateName: function(name) {
- return (name.length < 256);
- }
+ rootUrl: "controller/web/devices",
+ createTable: function(columnNames, body) {
+ var tableAttributes = ["table-striped", "table-bordered", "table-condensed"];
+ var $table = one.lib.dashlet.table.table(tableAttributes);
+ var tableHeaders = columnNames;
+ var $thead = one.lib.dashlet.table.header(tableHeaders);
+ var $tbody = one.lib.dashlet.table.body(body, tableHeaders);
+ $table.append($thead)
+ .append($tbody);
+ return $table;
+ },
+ validateName: function(name) {
+ return (name.length < 256);
+ }
};
one.f.switchmanager.nodesLearnt = {
- id: {
- dashlet: {
- popout: "one_f_switchmanager_nodesLearnt_id_dashlet_popout",
- datagrid: "one_f_switchmanager_nodesLearnt_id_dashlet_datagrid"
- },
- modal: {
- modal: "one_f_switchmanager_nodesLearnt_id_modal_modal",
- configure: "one_f_switchmanager_nodesLearnt_id_modal_configure",
- ports: "one_f_switchmanager_nodesLearnt_id_modal_ports",
- save: "one_f_switchmanager_nodesLearnt_id_modal_save",
- datagrid: "one_f_switchmanager_nodesLearnt_id_modal_datagrid",
- portsDatagrid: "one_f_switchmanager_nodesLearnt_id_modal_portsDatagrid",
- form: {
- nodeId: "one_f_switchmanager_nodesLearnt_id_modal_form_nodeid",
- nodeName : "one_f_switchmanager_nodesLearnt_id_modal_form_nodename",
- portStatus : "one_f_switchmanager_nodesLearnt_id_modal_form_portstatus",
- tier: "one_f_switchmanager_nodesLearnt_id_modal_form_tier",
- operationMode: "one_f_switchmanager_nodesLearnt_id_modal_form_opmode"
- }
- }
+ id: {
+ dashlet: {
+ popout: "one_f_switchmanager_nodesLearnt_id_dashlet_popout",
+ datagrid: "one_f_switchmanager_nodesLearnt_id_dashlet_datagrid"
},
- dashlet: function($dashlet) {
- var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
- one.lib.dashlet.empty($dashlet);
- $dashlet.append(one.lib.dashlet.header(one.f.dashlet.nodesLearnt.name));
-
- one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
- var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.dashlet.datagrid, {
- searchable: true,
- filterable: false,
- pagination: true,
- flexibleRowsPerPage: true
- }, "table-striped table-condensed");
- $dashlet.append($gridHTML);
- var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.abridged(content);
- $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
- $(this).find("tbody a").click(one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
- });
-
- $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
- $(this).find("tbody span").click(function(){
- one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
- });
- });
-
+ modal: {
+ modal: "one_f_switchmanager_nodesLearnt_id_modal_modal",
+ configure: "one_f_switchmanager_nodesLearnt_id_modal_configure",
+ ports: "one_f_switchmanager_nodesLearnt_id_modal_ports",
+ save: "one_f_switchmanager_nodesLearnt_id_modal_save",
+ datagrid: "one_f_switchmanager_nodesLearnt_id_modal_datagrid",
+ portsDatagrid: "one_f_switchmanager_nodesLearnt_id_modal_portsDatagrid",
+ form: {
+ nodeId: "one_f_switchmanager_nodesLearnt_id_modal_form_nodeid",
+ nodeName : "one_f_switchmanager_nodesLearnt_id_modal_form_nodename",
+ portStatus : "one_f_switchmanager_nodesLearnt_id_modal_form_portstatus",
+ tier: "one_f_switchmanager_nodesLearnt_id_modal_form_tier",
+ operationMode: "one_f_switchmanager_nodesLearnt_id_modal_form_opmode"
+ }
+ }
+ },
+ dashlet: function($dashlet) {
+ var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
+ one.lib.dashlet.empty($dashlet);
+ $dashlet.append(one.lib.dashlet.header(one.f.dashlet.nodesLearnt.name));
+
+ one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
+ var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.dashlet.datagrid, {
+ searchable: true,
+ filterable: false,
+ pagination: true,
+ flexibleRowsPerPage: true
+ }, "table-striped table-condensed");
+ $dashlet.append($gridHTML);
+ var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.abridged(content);
+ $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
+ $(this).find("tbody a").click(one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
+ });
+
+ $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
+ $(this).find("tbody span").click(function(){
+ one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
});
+ });
+
+ });
+ },
+ ajax : {
+ main : function(url, callback) {
+ $.getJSON(url, function(data) {
+ callback(data);
+ });
+ }
+ },
+ modal : {
+ initialize: {
+ updateNode: function(evt) {
+ one.f.switchmanager.nodesLearnt.ajax.main(one.f.switchmanager.rootUrl + "/tiers", function(tiers) {
+
+ var nodeId = decodeURIComponent(evt.target.id);
+ var h3;
+ var footer = [];
+ var $body = one.f.switchmanager.nodesLearnt.modal.body.updateNode(nodeId, JSON.parse(decodeURIComponent(evt.target.getAttribute("switchDetails"))), tiers);
+ if (evt.target.getAttribute("privilege") == 'WRITE'){
+ h3 = "Update Node Information";
+ footer = one.f.switchmanager.nodesLearnt.modal.footer.updateNode();
+ } else { //disable node edit
+ $body.find('*').attr('disabled', 'disabled');
+ h3 = 'Node Information';
+ }
+
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.configure, h3, "", footer);
+ // bind save button
+ $('#' + one.f.switchmanager.nodesLearnt.id.modal.save, $modal).click(function() {
+ one.f.switchmanager.nodesLearnt.modal.save($modal);
+ });
+
+ // inject body (nodePorts)
+ one.lib.modal.inject.body($modal, $body);
+ $modal.modal();
+ });
+ },
+ popout: function() {
+ var h3 = "Nodes Learned";
+ var footer = one.f.switchmanager.nodesLearnt.modal.footer.popout();
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.modal, h3, "", footer);
+ var $body = one.f.switchmanager.nodesLearnt.modal.body.popout($modal);
+ return $modal;
+ },
+ displayPorts: function(ports) {
+ var content = JSON.parse(decodeURIComponent(ports.attr("ports")));
+
+ var h3 = ((ports.attr("nodeName") == "None")? ports.attr("nodeId") : ports.attr("nodeName"))
+ var footer = [];
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.ports, h3, "", footer);
+
+ var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid, {
+ searchable: true,
+ filterable: false,
+ pagination: true,
+ flexibleRowsPerPage: true,
+ popout: true
+ }, "table-striped table-condensed");
+ one.lib.modal.inject.body($modal, $gridHTML);
+ $modal.on("shown", function() {
+ var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.displayPorts(content);
+ $("#" + one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid).datagrid({
+ dataSource: dataSource,
+ stretchHeight: false
+ });
+ });
+ $modal.modal();
+ }
},
- ajax : {
- main : function(url, callback) {
- $.getJSON(url, function(data) {
- callback(data);
- });
+ body: {
+ updateNode: function(nodeId, switchDetails, tiers) {
+ var $form = $(document.createElement('form'));
+ var $fieldset = $(document.createElement('fieldset'));
+ // node ID. not editable.
+ var $label = one.lib.form.label("Node ID");
+ var $input = one.lib.form.input("node id");
+ $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeId);
+ $input.attr("disabled", true);
+ $input.attr("value", nodeId);
+ $fieldset.append($label).append($input);
+ // node name
+ var $label = one.lib.form.label("Node Name");
+ var $input = one.lib.form.input("Node Name");
+ $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeName);
+ if(switchDetails["nodeName"] != null) {
+ $input.attr('value', switchDetails["nodeName"]);
+ }
+ $fieldset.append($label).append($input);
+ // node tier
+ var $label = one.lib.form.label("Tier");
+ var $select = one.lib.form.select.create(tiers);
+ $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.tier);
+ $select.val(switchDetails["tier"]);
+ $fieldset.append($label).append($select);
+ // operation mode
+ var $label = one.lib.form.label("Operation Mode");
+ var $select = one.lib.form.select.create(
+ ["Allow reactive forwarding", "Proactive forwarding only"]);
+ $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.operationMode);
+ if ((one.main.registry != undefined) && (one.main.registry.container != 'default')) {
+ $select.attr("disabled", true);
}
+ $select.val(switchDetails["mode"]);
+ $fieldset.append($label).append($select);
+ $form.append($fieldset);
+ return $form;
+ },
+ popout: function($modal) {
+ var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.datagrid, {
+ searchable: true,
+ filterable: false,
+ pagination: true,
+ flexibleRowsPerPage: true,
+ popout: true
+ }, "table-striped table-condensed");
+ one.lib.modal.inject.body($modal, $gridHTML);
+ // attach to shown event of modal
+ $modal.on("shown", function() {
+ var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
+ one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
+ var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.popout(content);
+ $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).datagrid({
+ dataSource: dataSource,
+ stretchHeight: false
+ })
+ .on("loaded", function() {
+ $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).find("tbody span").click(function(){
+ one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
+ });
+ });
+ });
+ });
+ }
},
- modal : {
- initialize: {
- updateNode: function(evt) {
- one.f.switchmanager.nodesLearnt.ajax.main(one.f.switchmanager.rootUrl + "/tiers", function(tiers) {
-
- var nodeId = decodeURIComponent(evt.target.id);
- var h3;
- var footer = [];
- var $body = one.f.switchmanager.nodesLearnt.modal.body.updateNode(nodeId, JSON.parse(decodeURIComponent(evt.target.getAttribute("switchDetails"))), tiers);
- if (evt.target.getAttribute("privilege") == 'WRITE'){
- h3 = "Update Node Information";
- footer = one.f.switchmanager.nodesLearnt.modal.footer.updateNode();
- } else { //disable node edit
- $body.find('*').attr('disabled', 'disabled');
- h3 = 'Node Information';
- }
-
- var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.configure, h3, "", footer);
- // bind save button
- $('#' + one.f.switchmanager.nodesLearnt.id.modal.save, $modal).click(function() {
- one.f.switchmanager.nodesLearnt.modal.save($modal);
- });
-
- // inject body (nodePorts)
- one.lib.modal.inject.body($modal, $body);
- $modal.modal();
- });
- },
- popout: function() {
- var h3 = "Nodes Learned";
- var footer = one.f.switchmanager.nodesLearnt.modal.footer.popout();
- var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.modal, h3, "", footer);
- var $body = one.f.switchmanager.nodesLearnt.modal.body.popout($modal);
- return $modal;
- },
- displayPorts: function(ports) {
- var content = JSON.parse(decodeURIComponent(ports.attr("ports")));
-
- var h3 = ((ports.attr("nodeName") == "None")? ports.attr("nodeId") : ports.attr("nodeName"))
- var footer = [];
- var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.ports, h3, "", footer);
-
- var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid, {
- searchable: true,
- filterable: false,
- pagination: true,
- flexibleRowsPerPage: true,
- popout: true
- }, "table-striped table-condensed");
- one.lib.modal.inject.body($modal, $gridHTML);
- $modal.on("shown", function() {
- var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.displayPorts(content);
- $("#" + one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid).datagrid({
- dataSource: dataSource,
- stretchHeight: false
- });
- });
- $modal.modal();
+ save: function($modal) {
+ var result = {};
+ result['nodeName'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeName, $modal).val();
+ if(!one.f.switchmanager.validateName(result['nodeName'])) {
+ alert("Node name can contain upto 255 characters");
+ return;
+ }
+ result['nodeId'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeId, $modal).val();
+ result['tier'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.tier, $modal).val();
+ result['operationMode'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.operationMode, $modal).val();
+ one.f.switchmanager.nodesLearnt.modal.ajax(result,
+ function(response) {
+ if(response.status == true) {
+ $modal.modal('hide');
+ one.topology.update(); // refresh visual topology with new name
+ // TODO: Identify dashlet by inserting a nodesLearnt div
+ // in the dashlet() instead
+ one.f.switchmanager.nodesLearnt.dashlet($("#left-top .dashlet"));
+ } else {
+ alert(response.message);
}
+
+ });
+ },
+ ajax: function(requestData, callback) {
+ $.getJSON(one.f.switchmanager.rootUrl + "/nodesLearnt/update", requestData, function(response) {
+ callback(response);
+ });
+ },
+ footer: {
+ updateNode: function() {
+ var footer = [];
+ var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.nodesLearnt.id.modal.save, "btn-primary", "");
+ var $saveButton = one.lib.dashlet.button.button(saveButton);
+ footer.push($saveButton);
+
+ return footer;
+ },
+ popout: function() {
+ // TODO: Maybe put a close button in the footer?
+ return [];
+ }
+ }
+ },
+ // data functions
+ data : {
+ gridDataSource: {
+ abridged: function(data) {
+ var source = new StaticDataSource({
+ columns: [
+ {
+ property: 'nodeName',
+ label: 'Node Name',
+ sortable: true
},
- body: {
- updateNode: function(nodeId, switchDetails, tiers) {
- var $form = $(document.createElement('form'));
- var $fieldset = $(document.createElement('fieldset'));
- // node ID. not editable.
- var $label = one.lib.form.label("Node ID");
- var $input = one.lib.form.input("node id");
- $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeId);
- $input.attr("disabled", true);
- $input.attr("value", nodeId);
- $fieldset.append($label).append($input);
- // node name
- var $label = one.lib.form.label("Node Name");
- var $input = one.lib.form.input("Node Name");
- $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeName);
- if(switchDetails["nodeName"] != null) {
- $input.attr('value', switchDetails["nodeName"]);
- }
- $fieldset.append($label).append($input);
- // node tier
- var $label = one.lib.form.label("Tier");
- var $select = one.lib.form.select.create(tiers);
- $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.tier);
- $select.val(switchDetails["tier"]);
- $fieldset.append($label).append($select);
- // operation mode
- var $label = one.lib.form.label("Operation Mode");
- var $select = one.lib.form.select.create(
- ["Allow reactive forwarding", "Proactive forwarding only"]);
- $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.operationMode);
- if ((one.main.registry != undefined) && (one.main.registry.container != 'default')) {
- $select.attr("disabled", true);
- }
- $select.val(switchDetails["mode"]);
- $fieldset.append($label).append($select);
- $form.append($fieldset);
- return $form;
- },
- popout: function($modal) {
- var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.datagrid, {
- searchable: true,
- filterable: false,
- pagination: true,
- flexibleRowsPerPage: true,
- popout: true
- }, "table-striped table-condensed");
- one.lib.modal.inject.body($modal, $gridHTML);
- // attach to shown event of modal
- $modal.on("shown", function() {
- var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
- one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
- var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.popout(content);
- $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).datagrid({
- dataSource: dataSource,
- stretchHeight: false
- })
- .on("loaded", function() {
- $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).find("tbody span").click(function(){
- one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
- });
- });
- });
- });
- }
+ {
+ property: 'nodeId',
+ label: 'Node ID',
+ sortable: true
},
- save: function($modal) {
- var result = {};
- result['nodeName'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeName, $modal).val();
- if(!one.f.switchmanager.validateName(result['nodeName'])) {
- alert("Node name can contain upto 255 characters");
- return;
- }
- result['nodeId'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeId, $modal).val();
- result['tier'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.tier, $modal).val();
- result['operationMode'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.operationMode, $modal).val();
- one.f.switchmanager.nodesLearnt.modal.ajax(result,
- function(response) {
- if(response.status == true) {
- $modal.modal('hide');
- one.topology.update(); // refresh visual topology with new name
- // TODO: Identify dashlet by inserting a nodesLearnt div
- // in the dashlet() instead
- one.f.switchmanager.nodesLearnt.dashlet($("#left-top .dashlet"));
- } else {
- alert(response.message);
- }
-
- });
+ {
+ property: 'ports',
+ label: 'Ports',
+ sortable: true
+ }
+ ],
+ data: data.nodeData,
+ formatter: function(items) {
+ $.each(items, function (index, item) {
+ var nodeName = item.nodeName;
+ var nodeNameEntry = item.nodeName ? item.nodeName : "Click to update";
+ item.nodeName = '<a href="#" id="' + item.nodeId + '" switchDetails=' + encodeURIComponent(JSON.stringify(item)) +
+ ' privilege=' + data.privilege + '>' + nodeNameEntry + '</a>';
+
+ var ports = item.ports;
+ var portsMatch = ports.match(/<\/span>/g);
+ var portsLength = 0;
+ if (portsMatch != null) {
+ portsLength = portsMatch.length;
+ }
+ item.ports = '<span class="nodePorts" style="cursor:pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
+ + '" nodeName="' + nodeName
+ + '">' + portsLength +'</span>';
+ });
},
- ajax: function(requestData, callback) {
- $.getJSON(one.f.switchmanager.rootUrl + "/nodesLearnt/update", requestData, function(response) {
- callback(response);
- });
+ delay: 0
+ });
+ return source;
+
+ },
+ popout: function(data) {
+ var source = new StaticDataSource({
+ columns: [
+ {
+ property: 'nodeName',
+ label: 'Node Name',
+ sortable: true
},
- footer: {
- updateNode: function() {
- var footer = [];
- var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.nodesLearnt.id.modal.save, "btn-primary", "");
- var $saveButton = one.lib.dashlet.button.button(saveButton);
- footer.push($saveButton);
-
- return footer;
- },
- popout: function() {
- // TODO: Maybe put a close button in the footer?
- return [];
- }
- }
- },
- // data functions
- data : {
- gridDataSource: {
- abridged: function(data) {
- var source = new StaticDataSource({
- columns: [
- {
- property: 'nodeName',
- label: 'Node Name',
- sortable: true
- },
- {
- property: 'nodeId',
- label: 'Node ID',
- sortable: true
- },
- {
- property: 'ports',
- label: 'Ports',
- sortable: true
- }
- ],
- data: data.nodeData,
- formatter: function(items) {
- $.each(items, function (index, item) {
- var nodeName = item.nodeName;
- var nodeNameEntry = item.nodeName ? item.nodeName : "Click to update";
- item.nodeName = '<a href="#" id="' + item.nodeId + '" switchDetails=' + encodeURIComponent(JSON.stringify(item)) +
- ' privilege=' + data.privilege + '>' + nodeNameEntry + '</a>';
-
- var ports = item.ports;
- var portsMatch = ports.match(/<\/span>/g);
- var portsLength = 0;
- if (portsMatch != null) {
- portsLength = portsMatch.length;
- }
- item.ports = '<span class="nodePorts" style="cursor:pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
- + '" nodeName="' + nodeName
- + '">' + portsLength +'</span>';
- });
- },
- delay: 0
- });
- return source;
-
- },
- popout: function(data) {
- var source = new StaticDataSource({
- columns: [
- {
- property: 'nodeName',
- label: 'Node Name',
- sortable: true
- },
- {
- property: 'nodeId',
- label: 'Node ID',
- sortable: true
- },
- {
- property: 'tierName',
- label: 'Tier Name',
- sortable: true
- },
- {
- property: 'mac',
- label: 'MAC Address',
- sortable: true
- },
- {
- property: 'ports',
- label: 'Ports',
- sortable: true
- }
- ],
- data: data.nodeData,
- formatter: function(items) {
- $.each(items, function (index, item) {
- var ports = item.ports;
- var portsMatch = ports.match(/<\/span>/g);
- var portsLength = 0;
- if (portsMatch != null) {
- portsLength = portsMatch.length;
- }
- item.ports = '<span class="nodePorts" style="cursor: pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
- + '" nodeName="' + item.nodeName
- + '">' + portsLength +'</span>';
- });
- },
- delay: 0
- });
- return source;
- },
- displayPorts: function(content){
- var data=[];
- var start=0;;
- var finish=content.indexOf("<br>",start);
- while(finish != -1){
- data.push({"ports":content.substring(start,finish)});
- start=finish+4
- finish=content.indexOf("<br>",start);
- }
- var source = new StaticDataSource({
- columns: [
- {
- property: 'ports',
- label: 'Ports',
- sortable: true
- }
- ],
- data:data,
- delay: 0
- });
-
- return source;
- }
+ {
+ property: 'nodeId',
+ label: 'Node ID',
+ sortable: true
},
- abridged : function(data) {
- var result = [];
- $.each(data.nodeData, function(key, value) {
- var tr = {};
- var entry = [];
- var nodeNameEntry = value["nodeName"] ? value["nodeName"] : "Click to update";
-
- // TODO: Move anchor tag creation to one.lib.form.
- var aTag;
- aTag = document.createElement("a");
- aTag.privilege = data.privilege;
- aTag.addEventListener("click", one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
- aTag.addEventListener("mouseover", function(evt) {
- evt.target.style.cursor = "pointer";
- }, false);
- aTag.setAttribute("id", encodeURIComponent(value["nodeId"]));
- aTag.switchDetails = value;
- aTag.innerHTML = nodeNameEntry;
- entry.push(aTag);
- entry.push(value["nodeId"]);
- entry.push(value["ports"]);
- tr.entry = entry;
- result.push(tr);
- });
- return result;
+ {
+ property: 'tierName',
+ label: 'Tier Name',
+ sortable: true
},
- popout : function(data) {
- var result = [];
- $.each(data.nodeData, function(key, value) {
- var tr = {};
- // fill up all the td's
- var entry = [];
- var nodenameentry = value["nodeName"] ? value["nodeName"] : "No name provided";
- entry.push(nodenameentry);
- entry.push(value["nodeId"]);
- entry.push(value["tierName"]);
- entry.push(value["mac"]);
- entry.push(value["ports"]);
- tr.entry = entry;
- result.push(tr);
- });
- return result;
+ {
+ property: 'mac',
+ label: 'MAC Address',
+ sortable: true
+ },
+ {
+ property: 'ports',
+ label: 'Ports',
+ sortable: true
}
+ ],
+ data: data.nodeData,
+ formatter: function(items) {
+ $.each(items, function (index, item) {
+ var ports = item.ports;
+ var portsMatch = ports.match(/<\/span>/g);
+ var portsLength = 0;
+ if (portsMatch != null) {
+ portsLength = portsMatch.length;
+ }
+ item.ports = '<span class="nodePorts" style="cursor: pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
+ + '" nodeName="' + item.nodeName
+ + '">' + portsLength +'</span>';
+ });
+ },
+ delay: 0
+ });
+ return source;
+ },
+ displayPorts: function(content){
+ var data=[];
+ var start=0;;
+ var finish=content.indexOf("<br>",start);
+ while(finish != -1){
+ data.push({"ports":content.substring(start,finish)});
+ start=finish+4
+ finish=content.indexOf("<br>",start);
+ }
+ var source = new StaticDataSource({
+ columns: [
+ {
+ property: 'ports',
+ label: 'Ports',
+ sortable: true
+ }
+ ],
+ data:data,
+ delay: 0
+ });
+
+ return source;
+ }
+ },
+ abridged : function(data) {
+ var result = [];
+ $.each(data.nodeData, function(key, value) {
+ var tr = {};
+ var entry = [];
+ var nodeNameEntry = value["nodeName"] ? value["nodeName"] : "Click to update";
+
+ // TODO: Move anchor tag creation to one.lib.form.
+ var aTag;
+ aTag = document.createElement("a");
+ aTag.privilege = data.privilege;
+ aTag.addEventListener("click", one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
+ aTag.addEventListener("mouseover", function(evt) {
+ evt.target.style.cursor = "pointer";
+ }, false);
+ aTag.setAttribute("id", encodeURIComponent(value["nodeId"]));
+ aTag.switchDetails = value;
+ aTag.innerHTML = nodeNameEntry;
+ entry.push(aTag);
+ entry.push(value["nodeId"]);
+ entry.push(value["ports"]);
+ tr.entry = entry;
+ result.push(tr);
+ });
+ return result;
+ },
+ popout : function(data) {
+ var result = [];
+ $.each(data.nodeData, function(key, value) {
+ var tr = {};
+ // fill up all the td's
+ var entry = [];
+ var nodenameentry = value["nodeName"] ? value["nodeName"] : "No name provided";
+ entry.push(nodenameentry);
+ entry.push(value["nodeId"]);
+ entry.push(value["tierName"]);
+ entry.push(value["mac"]);
+ entry.push(value["ports"]);
+ tr.entry = entry;
+ result.push(tr);
+ });
+ return result;
}
+ }
};
one.f.switchmanager.subnetGatewayConfig = {
- id: {
- dashlet: {
- addIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addIP",
- addPorts: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addPorts",
- removeIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_removeIP",
- datagrid: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_datagrid",
- selectAll: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_selectAll"
- },
- modal: {
- modal: "one_f_switchmanager_subnetGatewayConfig_id_modal_modal",
- ports : "one_f_switchmanager_subnetGatewayConfig_id_modal_ports",
- save: "one_f_switchmanager_subnetGatewayConfig_id_modal_save",
- remove: "one_f_switchmanager_subnetGatewayConfig_id_modal_remove",
- cancel: "one_f_switchmanager_subnetGatewayConfig_id_modal_cancel",
- form: {
- name : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayname",
- gatewayIPAddress : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayipaddress",
- nodeId: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_nodeid",
- ports: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_ports"
- }
+ id: {
+ dashlet: {
+ addIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addIP",
+ addPorts: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addPorts",
+ removeIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_removeIP",
+ datagrid: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_datagrid",
+ selectAll: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_selectAll"
+ },
+ modal: {
+ modal: "one_f_switchmanager_subnetGatewayConfig_id_modal_modal",
+ ports : "one_f_switchmanager_subnetGatewayConfig_id_modal_ports",
+ save: "one_f_switchmanager_subnetGatewayConfig_id_modal_save",
+ remove: "one_f_switchmanager_subnetGatewayConfig_id_modal_remove",
+ cancel: "one_f_switchmanager_subnetGatewayConfig_id_modal_cancel",
+ form: {
+ name : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayname",
+ gatewayIPAddress : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayipaddress",
+ nodeId: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_nodeid",
+ ports: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_ports"
+ }
+ }
+ },
+ // device ajax calls
+ dashlet: function($dashlet) {
+ one.lib.dashlet.empty($dashlet);
+ $dashlet.append(one.lib.dashlet.header(one.f.dashlet.subnetGatewayConfig.name));
+ // Add gateway IP Address button
+ var url = one.f.switchmanager.rootUrl + "/subnets";
+ one.f.switchmanager.subnetGatewayConfig.ajax.main(url, {}, function(content) {
+
+ if (content.privilege === 'WRITE') {
+ var button = one.lib.dashlet.button.single("Add Gateway IP Address",
+ one.f.switchmanager.subnetGatewayConfig.id.dashlet.addIPAddress, "btn-primary", "btn-mini");
+ var $button = one.lib.dashlet.button.button(button);
+ $button.click(function() {
+ var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.gateway();
+ $modal.modal();
+ });
+ $dashlet.append($button);
+
+ // Delete gateway ip address button
+ var button = one.lib.dashlet.button.single("Remove Gateway IP Address",
+ one.f.switchmanager.subnetGatewayConfig.id.dashlet.removeIPAddress, "btn-danger", "btn-mini");
+ var $button = one.lib.dashlet.button.button(button);
+ $button.click(function() {
+ var gatewaysToDelete = [];
+ var checkedCheckBoxes = $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find("tbody input:checked")
+ checkedCheckBoxes.each(function(index, value) {
+ gatewaysToDelete.push(checkedCheckBoxes[index].id);
+ });
+ if (checkedCheckBoxes.size() === 0) {
+ return false;
}
- },
- // device ajax calls
- dashlet: function($dashlet) {
- one.lib.dashlet.empty($dashlet);
- $dashlet.append(one.lib.dashlet.header(one.f.dashlet.subnetGatewayConfig.name));
- // Add gateway IP Address button
- var url = one.f.switchmanager.rootUrl + "/subnets";
- one.f.switchmanager.subnetGatewayConfig.ajax.main(url, {}, function(content) {
-
- if (content.privilege === 'WRITE') {
- var button = one.lib.dashlet.button.single("Add Gateway IP Address",
- one.f.switchmanager.subnetGatewayConfig.id.dashlet.addIPAddress, "btn-primary", "btn-mini");
- var $button = one.lib.dashlet.button.button(button);
- $button.click(function() {
- var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.gateway();
- $modal.modal();
- });
- $dashlet.append($button);
-
- // Delete gateway ip address button
- var button = one.lib.dashlet.button.single("Remove Gateway IP Address",
- one.f.switchmanager.subnetGatewayConfig.id.dashlet.removeIPAddress, "btn-danger", "btn-mini");
- var $button = one.lib.dashlet.button.button(button);
- $button.click(function() {
- var gatewaysToDelete = [];
- var checkedCheckBoxes = $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find("tbody input:checked")
- checkedCheckBoxes.each(function(index, value) {
- gatewaysToDelete.push(checkedCheckBoxes[index].id);
- });
- if (checkedCheckBoxes.size() === 0) {
- return false;
- }
- one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.dialog(gatewaysToDelete)
- });
- $dashlet.append($button);
-
- // Add Ports button
- var button = one.lib.dashlet.button.single("Add Ports",
- one.f.switchmanager.subnetGatewayConfig.id.dashlet.addPorts, "btn-primary", "btn-mini");
- var $button = one.lib.dashlet.button.button(button);
- $button.click(function() {
- if (one.f.switchmanager.subnetGatewayConfig.registry.gateways.length === 0) {
- alert('No Gateways Exist');
- return false;
- }
- var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.ports();
- $modal.modal();
- });
- $dashlet.append($button);
+ one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.dialog(gatewaysToDelete)
+ });
+ $dashlet.append($button);
+
+ // Add Ports button
+ var button = one.lib.dashlet.button.single("Add Ports",
+ one.f.switchmanager.subnetGatewayConfig.id.dashlet.addPorts, "btn-primary", "btn-mini");
+ var $button = one.lib.dashlet.button.button(button);
+ $button.click(function() {
+ if (one.f.switchmanager.subnetGatewayConfig.registry.gateways.length === 0) {
+ alert('No Gateways Exist');
+ return false;
+ }
+ var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.ports();
+ $modal.modal();
+ });
+ $dashlet.append($button);
+ }
+ var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid, {
+ searchable: true,
+ filterable: false,
+ pagination: true,
+ flexibleRowsPerPage: true
+ }, "table-striped table-condensed");
+ $dashlet.append($gridHTML);
+ var dataSource = one.f.switchmanager.subnetGatewayConfig.data.devicesgrid(content);
+ $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
+ .on("loaded", function() {
+ $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).click(function() {
+ $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
+ $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).is(':checked'));
+ });
+ $(".subnetGatewayConfig").click(function(e){
+ if (!$('.subnetGatewayConfig[type=checkbox]:not(:checked)').length) {
+ $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
+ .prop("checked",
+ true);
+ } else {
+ $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
+ .prop("checked",
+ false);
}
- var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid, {
- searchable: true,
- filterable: false,
- pagination: true,
- flexibleRowsPerPage: true
- }, "table-striped table-condensed");
- $dashlet.append($gridHTML);
- var dataSource = one.f.switchmanager.subnetGatewayConfig.data.devicesgrid(content);
- $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
- .on("loaded", function() {
- $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).click(function() {
- $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
- $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).is(':checked'));
- });
- $(".subnetGatewayConfig").click(function(e){
- if (!$('.subnetGatewayConfig[type=checkbox]:not(:checked)').length) {
- $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
- .prop("checked",
- true);
- } else {
- $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
- .prop("checked",
- false);
- }
- e.stopPropagation();
- });
- });
+ e.stopPropagation();
+ });
});
+ });
+ },
+ ajax : {
+ main : function(url, requestData, callback) {
+ $.getJSON(url, requestData, function(data) {
+ callback(data);
+ });
+ }
+ },
+ registry: {},
+ modal : {
+ initialize: {
+ gateway: function() {
+ var h3 = "Add Gateway IP Address";
+ var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, "", footer);
+ // bind save button
+ $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
+ one.f.switchmanager.subnetGatewayConfig.modal.save.gateway($modal);
+ });
+ var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.gateway();
+ one.lib.modal.inject.body($modal, $body);
+ return $modal;
+ },
+ ports: function() {
+ var h3 = "Add Ports";
+ var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.ports, h3, "", footer);
+ // bind save button
+ $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
+ one.f.switchmanager.subnetGatewayConfig.modal.save.ports($modal);
+ });
+
+ // TODO: Change to subnetGateway instead.
+ one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
+ var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.ports(nodes, nodeports);
+ one.lib.modal.inject.body($modal, $body);
+ });
+ return $modal;
+ }
},
- ajax : {
- main : function(url, requestData, callback) {
- $.getJSON(url, requestData, function(data) {
- callback(data);
+ save: {
+ gateway: function($modal) {
+ var result = {};
+ result['gatewayName'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
+ if(!one.f.switchmanager.validateName(result['gatewayName'])) {
+ alert("Gateway name can contain upto 255 characters");
+ return;
+ }
+ result['gatewayIPAddress'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress, $modal).val();
+ one.f.switchmanager.subnetGatewayConfig.modal.ajax.gateway(result,
+ function(response) {
+ if(response.status == true) {
+ $modal.modal('hide');
+ one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
+ } else {
+ alert(response.message);
+ }
});
+ },
+ ports: function($modal) {
+ var result = {};
+ var gatewayRegistryIndex = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
+ result['portsName'] = one.f.switchmanager.subnetGatewayConfig.registry.gateways[gatewayRegistryIndex];
+ result['nodeId'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId, $modal).val();
+ result['ports'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports, $modal).val();
+ if(!result['portsName'] || result['portsName'] == "") {
+ alert("No gateway chosen. Cannot add port");
+ return;
}
- },
- registry: {},
- modal : {
- initialize: {
- gateway: function() {
- var h3 = "Add Gateway IP Address";
- var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
- var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, "", footer);
- // bind save button
- $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
- one.f.switchmanager.subnetGatewayConfig.modal.save.gateway($modal);
- });
- var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.gateway();
- one.lib.modal.inject.body($modal, $body);
- return $modal;
- },
- ports: function() {
- var h3 = "Add Ports";
- var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
- var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.ports, h3, "", footer);
- // bind save button
- $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
- one.f.switchmanager.subnetGatewayConfig.modal.save.ports($modal);
- });
-
- // TODO: Change to subnetGateway instead.
- one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
- var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.ports(nodes, nodeports);
- one.lib.modal.inject.body($modal, $body);
- });
- return $modal;
- }
- },
- save: {
- gateway: function($modal) {
- var result = {};
- result['gatewayName'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
- if(!one.f.switchmanager.validateName(result['gatewayName'])) {
- alert("Gateway name can contain upto 255 characters");
- return;
- }
- result['gatewayIPAddress'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress, $modal).val();
- one.f.switchmanager.subnetGatewayConfig.modal.ajax.gateway(result,
- function(response) {
- if(response.status == true) {
- $modal.modal('hide');
- one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
- } else {
- alert(response.message);
- }
- });
- },
- ports: function($modal) {
- var result = {};
- var gatewayRegistryIndex = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
- result['portsName'] = one.f.switchmanager.subnetGatewayConfig.registry.gateways[gatewayRegistryIndex];
- result['nodeId'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId, $modal).val();
- result['ports'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports, $modal).val();
- if(!result['portsName'] || result['portsName'] == "") {
- alert("No gateway chosen. Cannot add port");
- return;
- }
- if(!result['nodeId'] || result['nodeId'] == "") {
- alert("Please select a node.");
- return;
- }
- if(!result['ports'] || result['ports'] == "") {
- alert("Please choose a port.");
- return;
- }
- one.f.switchmanager.subnetGatewayConfig.modal.ajax.ports(result,
- function(response) {
- if(response.status == true) {
- $modal.modal('hide');
- one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
- } else {
- alert(response.message);
- }
- });
- }
- },
- body: {
- gateway: function() {
- var $form = $(document.createElement('form'));
- var $fieldset = $(document.createElement('fieldset'));
- // gateway name
- var $label = one.lib.form.label("Name");
- var $input = one.lib.form.input("Name");
- $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
- $fieldset.append($label).append($input);
- // gateway IP Mask
- var $label = one.lib.form.label("Gateway IP Address/Mask");
- var $input = one.lib.form.input("Gateway IP Address/Mask");
- var $help = one.lib.form.help('Example: 192.168.10.254/16');
- $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress);
- $fieldset.append($label).append($input).append($help);
-
- $form.append($fieldset);
- return $form;
- },
- ports: function(nodes, nodeports) {
- var $form = $(document.createElement('form'));
- var $fieldset = $(document.createElement('fieldset'));
- // gateways drop down
- var $label = one.lib.form.label("Gateway Name");
- var $select = one.lib.form.select.create(one.f.switchmanager.subnetGatewayConfig.registry.gateways);
- $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
- one.lib.form.select.prepend($select, { '' : 'Please Select a Gateway' });
- $select.val($select.find("option:first").val());
- $fieldset.append($label).append($select);
-
- // node ID
- var $label = one.lib.form.label("Node ID");
- var $select = one.lib.form.select.create(nodes);
- $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId);
- one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
- $select.val($select.find("option:first").val());
- $fieldset.append($label).append($select);
-
- // bind onchange
- $select.change(function() {
- // retrieve port value
- var node = $(this).find('option:selected').attr('value');
- one.f.switchmanager.subnetGatewayConfig.registry['currentNode'] = node;
- var $ports = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
- var ports = nodeports[node];
- var options = {};
- $(ports).each(function(idx, val) {
- options[val.internalPortName] = val.portName+' ('+val.portId+')';
- });
- one.lib.form.select.inject($ports, options);
- one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
- $ports.val($ports.find("option:first").val());
- });
-
- // ports
- var $label = one.lib.form.label("Select Port");
- var $select = one.lib.form.select.create();
- one.lib.form.select.prepend($select, { '' : 'Please Select a Port' });
- $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
- $fieldset.append($label).append($select);
-
- $form.append($fieldset);
- return $form;
- }
- },
- ajax: {
- gateway: function(requestData, callback) {
- $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/add", requestData, function(data) {
- callback(data);
+ if(!result['nodeId'] || result['nodeId'] == "") {
+ alert("Please select a node.");
+ return;
+ }
+ if(!result['ports'] || result['ports'] == "") {
+ alert("Please choose a port.");
+ return;
+ }
+ one.f.switchmanager.subnetGatewayConfig.modal.ajax.ports(result,
+ function(response) {
+ if(response.status == true) {
+ $modal.modal('hide');
+ one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
+ } else {
+ alert(response.message);
+ }
});
- },
- ports: function(requestData, callback) {
- $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/ports/add", requestData, function(data) {
- callback(data);
+ }
+ },
+ body: {
+ gateway: function() {
+ var $form = $(document.createElement('form'));
+ var $fieldset = $(document.createElement('fieldset'));
+ // gateway name
+ var $label = one.lib.form.label("Name");
+ var $input = one.lib.form.input("Name");
+ $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
+ $fieldset.append($label).append($input);
+ // gateway IP Mask
+ var $label = one.lib.form.label("Gateway IP Address/Mask");
+ var $input = one.lib.form.input("Gateway IP Address/Mask");
+ var $help = one.lib.form.help('Example: 192.168.10.254/16');
+ $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress);
+ $fieldset.append($label).append($input).append($help);
+
+ $form.append($fieldset);
+ return $form;
+ },
+ ports: function(nodes, nodeports) {
+ var $form = $(document.createElement('form'));
+ var $fieldset = $(document.createElement('fieldset'));
+ // gateways drop down
+ var $label = one.lib.form.label("Gateway Name");
+ var $select = one.lib.form.select.create(one.f.switchmanager.subnetGatewayConfig.registry.gateways);
+ $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
+ one.lib.form.select.prepend($select, { '' : 'Please Select a Gateway' });
+ $select.val($select.find("option:first").val());
+ $fieldset.append($label).append($select);
+
+ // node ID
+ var $label = one.lib.form.label("Node ID");
+ var $select = one.lib.form.select.create(nodes);
+ $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId);
+ one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
+ $select.val($select.find("option:first").val());
+ $fieldset.append($label).append($select);
+
+ // bind onchange
+ $select.change(function() {
+ // retrieve port value
+ var node = $(this).find('option:selected').attr('value');
+ one.f.switchmanager.subnetGatewayConfig.registry['currentNode'] = node;
+ var $ports = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
+ var ports = nodeports[node];
+ var options = {};
+ $(ports).each(function(idx, val) {
+ options[val.internalPortName] = val.portName+' ('+val.portId+')';
+ });
+ one.lib.form.select.inject($ports, options);
+ one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
+ $ports.val($ports.find("option:first").val());
});
- }
- },
- footer : function() {
- var footer = [];
- var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.subnetGatewayConfig.id.modal.save, "btn-primary", "");
- var $saveButton = one.lib.dashlet.button.button(saveButton);
- footer.push($saveButton);
- return footer;
- },
- removeMultiple: {
- dialog: function(gatewaysToDelete) {
- var h3 = 'Remove Gateway IP Address';
-
- var footer = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.footer();
- var $body = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.body(gatewaysToDelete);
- var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, $body, footer);
-
- // bind close button
- $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, $modal).click(function() {
- $modal.modal('hide');
- });
-
- // bind remove rule button
- $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.remove, $modal).click(this, function(e) {
- var requestData = {};
- if (gatewaysToDelete.length > 0) {
- requestData["gatewaysToDelete"] = gatewaysToDelete.toString();
- var url = one.f.switchmanager.rootUrl + "/subnetGateway/delete";
- one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
- $modal.modal('hide');
- if (response.status == true) {
- // refresh dashlet by passing dashlet div as param
- one.lib.alert("Gateway IP Address(es) successfully removed");
- } else {
- alert(response.message);
- }
- one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
- });
- }
- });
- $modal.modal();
- },
- footer : function() {
- var footer = [];
- var remove = one.lib.dashlet.button.single('Remove Gateway IP Address',one.f.switchmanager.subnetGatewayConfig.id.modal.remove, 'btn-danger', '');
- var $remove = one.lib.dashlet.button.button(remove);
- footer.push($remove);
-
- var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, '', '');
- var $cancel = one.lib.dashlet.button.button(cancel);
- footer.push($cancel);
-
- return footer;
- },
- body : function (gatewayList) {
- var $p = $(document.createElement('p'));
- var p = 'Remove the following Gateway IP Address(es)?';
- //creata a BS label for each rule and append to list
- $(gatewayList).each(function(){
- var $span = $(document.createElement('span'));
- $span.append(this);
- p += '<br/>' + $span[0].outerHTML;
- });
- $p.append(p);
- return $p;
- }
- }
+
+ // ports
+ var $label = one.lib.form.label("Select Port");
+ var $select = one.lib.form.select.create();
+ one.lib.form.select.prepend($select, { '' : 'Please Select a Port' });
+ $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
+ $fieldset.append($label).append($select);
+
+ $form.append($fieldset);
+ return $form;
+ }
},
- // data functions
- data : {
- devicesgrid: function(data) {
- one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
- var source = new StaticDataSource({
- columns: [
- {
- property: 'selector',
- label: "<input type='checkbox' id='"
- +one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll+"'/>",
- sortable: false
- },
- {
- property: 'name',
- label: 'Name',
- sortable: true
- },
- {
- property: 'subnet',
- label: 'Gateway IP Address/Mask',
- sortable: true
- },
- {
- property: 'nodePorts',
- label: 'Ports',
- sortable: false
- }
- ],
- data: data.nodeData,
- formatter: function(items) {
- $.each(items, function(index, tableRow) {
- tableRow["selector"] = '<input type="checkbox" class="subnetGatewayConfig" id="'
- + tableRow["name"] + '"></input>';
- var json = tableRow["nodePorts"];
- var nodePorts = JSON.parse(json);
- var nodePortHtml = "<div>";
- $.each(nodePorts, function(index, nodePort) {
- nodePortHtml += nodePort["nodePortName"] + " @ " + nodePort["nodeName"];
- nodePortHtml += " ";
- nodePortHtml += '<a href="#" id="' + encodeURIComponent(nodePort["nodePortId"]) +
- '" gatewayName="' + tableRow["name"] +
- '" onclick="javascript:one.f.switchmanager.subnetGatewayConfig.actions.deleteNodePort(this);">Remove</a>';
- nodePortHtml += "<br/>";
- });
- nodePortHtml += "</div>";
- tableRow["nodePorts"] = nodePortHtml;
- });
-
- },
- delay: 0
- });
- // populate the registry with subnet names
- one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
- $.each(data.nodeData, function(key, value) {
- one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
- });
- return source;
- },
- devices : function(data) {
- var result = [];
- one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
- $.each(data.nodeData, function(key, value) {
- var tr = {};
- // fill up all the td's
- var subnetConfigObject = $.parseJSON(value["json"]);
- var nodePorts = subnetConfigObject.nodePorts;
- var $nodePortsContainer = $(document.createElement("div"));
-
- for(var i = 0; i < nodePorts.length; i++) {
- var nodePort = nodePorts[i];
- $nodePortsContainer.append(nodePort + " ");
- // add delete anchor tag to delete ports
- var aTag = document.createElement("a");
- aTag.setAttribute("id", encodeURIComponent(nodePort));
- aTag.gatewayName = value["name"];
- aTag.addEventListener("click", function(evt) {
- var htmlPortAnchor = evt.target;
- var requestData = {};
- requestData["gatewayName"] = evt.target.gatewayName;
- requestData["nodePort"] = decodeURIComponent(evt.target.id);
- // make ajax call to delete port
- var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
- one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
- if(response.status == true) {
- // refresh dashlet by passing dashlet div as param
- one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
- } else {
- alert(response.message);
- }
- });
-
- });
- aTag.addEventListener("mouseover", function(evt) {
- evt.target.style.cursor = "pointer";
- }, false);
- aTag.innerHTML = "Remove";
- $nodePortsContainer.append(aTag);
- $nodePortsContainer.append("<br/>");
- }
-
- // store gateways in the registry so that they can be used in the add ports popup
- one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
- var entry = [];
- var checkbox = document.createElement("input");
- checkbox.setAttribute("type", "checkbox");
- checkbox.setAttribute("id", value["name"]);
- entry.push(checkbox);
- entry.push(value["name"]);
- entry.push(value["subnet"]);
- entry.push($nodePortsContainer);
- tr.entry = entry;
- result.push(tr);
+ ajax: {
+ gateway: function(requestData, callback) {
+ $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/add", requestData, function(data) {
+ callback(data);
+ });
+ },
+ ports: function(requestData, callback) {
+ $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/ports/add", requestData, function(data) {
+ callback(data);
+ });
+ }
+ },
+ footer : function() {
+ var footer = [];
+ var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.subnetGatewayConfig.id.modal.save, "btn-primary", "");
+ var $saveButton = one.lib.dashlet.button.button(saveButton);
+ footer.push($saveButton);
+ return footer;
+ },
+ removeMultiple: {
+ dialog: function(gatewaysToDelete) {
+ var h3 = 'Remove Gateway IP Address';
+
+ var footer = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.footer();
+ var $body = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.body(gatewaysToDelete);
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, $body, footer);
+
+ // bind close button
+ $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, $modal).click(function() {
+ $modal.modal('hide');
+ });
+
+ // bind remove rule button
+ $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.remove, $modal).click(this, function(e) {
+ var requestData = {};
+ if (gatewaysToDelete.length > 0) {
+ requestData["gatewaysToDelete"] = gatewaysToDelete.toString();
+ var url = one.f.switchmanager.rootUrl + "/subnetGateway/delete";
+ one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
+ $modal.modal('hide');
+ if (response.status == true) {
+ // refresh dashlet by passing dashlet div as param
+ one.lib.alert("Gateway IP Address(es) successfully removed");
+ } else {
+ alert(response.message);
+ }
+ one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
});
- return result;
- }
+ }
+ });
+ $modal.modal();
+ },
+ footer : function() {
+ var footer = [];
+ var remove = one.lib.dashlet.button.single('Remove Gateway IP Address',one.f.switchmanager.subnetGatewayConfig.id.modal.remove, 'btn-danger', '');
+ var $remove = one.lib.dashlet.button.button(remove);
+ footer.push($remove);
+
+ var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, '', '');
+ var $cancel = one.lib.dashlet.button.button(cancel);
+ footer.push($cancel);
+
+ return footer;
+ },
+ body : function (gatewayList) {
+ var $p = $(document.createElement('p'));
+ var p = 'Remove the following Gateway IP Address(es)?';
+ //creata a BS label for each rule and append to list
+ $(gatewayList).each(function(){
+ var $span = $(document.createElement('span'));
+ $span.append(this);
+ p += '<br/>' + $span[0].outerHTML;
+ });
+ $p.append(p);
+ return $p;
+ }
+ }
+ },
+ // data functions
+ data : {
+ devicesgrid: function(data) {
+ one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
+ var source = new StaticDataSource({
+ columns: [
+ {
+ property: 'selector',
+ label: "<input type='checkbox' id='"
+ +one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll+"'/>",
+ sortable: false
+ },
+ {
+ property: 'name',
+ label: 'Name',
+ sortable: true
+ },
+ {
+ property: 'subnet',
+ label: 'Gateway IP Address/Mask',
+ sortable: true
+ },
+ {
+ property: 'nodePorts',
+ label: 'Ports',
+ sortable: false
+ }
+ ],
+ data: data.nodeData,
+ formatter: function(items) {
+ $.each(items, function(index, tableRow) {
+ tableRow["selector"] = '<input type="checkbox" class="subnetGatewayConfig" id="'
+ + tableRow["name"] + '"></input>';
+ var json = tableRow["nodePorts"];
+ var nodePorts = JSON.parse(json);
+ var nodePortHtml = "<div>";
+ $.each(nodePorts, function(index, nodePort) {
+ nodePortHtml += nodePort["nodePortName"] + " @ " + nodePort["nodeName"];
+ nodePortHtml += " ";
+ nodePortHtml += '<a href="#" id="' + encodeURIComponent(nodePort["nodePortId"]) +
+ '" gatewayName="' + tableRow["name"] +
+ '" onclick="javascript:one.f.switchmanager.subnetGatewayConfig.actions.deleteNodePort(this);">Remove</a>';
+ nodePortHtml += "<br/>";
+ });
+ nodePortHtml += "</div>";
+ tableRow["nodePorts"] = nodePortHtml;
+ });
+
+ },
+ delay: 0
+ });
+ // populate the registry with subnet names
+ one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
+ $.each(data.nodeData, function(key, value) {
+ one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
+ });
+ return source;
},
- actions: {
- deleteNodePort: function(htmlPortAnchor) {
+ devices : function(data) {
+ var result = [];
+ one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
+ $.each(data.nodeData, function(key, value) {
+ var tr = {};
+ // fill up all the td's
+ var subnetConfigObject = $.parseJSON(value["json"]);
+ var nodePorts = subnetConfigObject.nodePorts;
+ var $nodePortsContainer = $(document.createElement("div"));
+
+ for(var i = 0; i < nodePorts.length; i++) {
+ var nodePort = nodePorts[i];
+ $nodePortsContainer.append(nodePort + " ");
+ // add delete anchor tag to delete ports
+ var aTag = document.createElement("a");
+ aTag.setAttribute("id", encodeURIComponent(nodePort));
+ aTag.gatewayName = value["name"];
+ aTag.addEventListener("click", function(evt) {
+ var htmlPortAnchor = evt.target;
var requestData = {};
- requestData["gatewayName"] = htmlPortAnchor.getAttribute("gatewayName");
- requestData["nodePort"] = decodeURIComponent(htmlPortAnchor.id);
+ requestData["gatewayName"] = evt.target.gatewayName;
+ requestData["nodePort"] = decodeURIComponent(evt.target.id);
// make ajax call to delete port
var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
- if(response.status == true) {
- // refresh dashlet by passing dashlet div as param
- one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
- } else {
- alert(response.message);
- }
+ if(response.status == true) {
+ // refresh dashlet by passing dashlet div as param
+ one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
+ } else {
+ alert(response.message);
+ }
});
+
+ });
+ aTag.addEventListener("mouseover", function(evt) {
+ evt.target.style.cursor = "pointer";
+ }, false);
+ aTag.innerHTML = "Remove";
+ $nodePortsContainer.append(aTag);
+ $nodePortsContainer.append("<br/>");
+ }
+
+ // store gateways in the registry so that they can be used in the add ports popup
+ one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
+ var entry = [];
+ var checkbox = document.createElement("input");
+ checkbox.setAttribute("type", "checkbox");
+ checkbox.setAttribute("id", value["name"]);
+ entry.push(checkbox);
+ entry.push(value["name"]);
+ entry.push(value["subnet"]);
+ entry.push($nodePortsContainer);
+ tr.entry = entry;
+ result.push(tr);
+ });
+ return result;
+ }
+ },
+ actions: {
+ deleteNodePort: function(htmlPortAnchor) {
+ var requestData = {};
+ requestData["gatewayName"] = htmlPortAnchor.getAttribute("gatewayName");
+ requestData["nodePort"] = decodeURIComponent(htmlPortAnchor.id);
+ // make ajax call to delete port
+ var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
+ one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
+ if(response.status == true) {
+ // refresh dashlet by passing dashlet div as param
+ one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
+ } else {
+ alert(response.message);
}
+ });
}
+ }
}
one.f.switchmanager.staticRouteConfig = {
- id: {
- dashlet: {
- add: "one_f_switchmanager_staticRouteConfig_id_dashlet_add",
- remove: "one_f_switchmanager_staticRouteConfig_id_dashlet_remove",
- datagrid: "one_f_switchmanager_staticRouteConfig_id_dashlet_datagrid",
- selectAll: "one_f_switchmanager_staticRouteConfig_id_dashlet_selectAll"
- },
- modal: {
- modal: "one_f_switchmanager_staticRouteConfig_id_modal_modal",
- save: "one_f_switchmanager_staticRouteConfig_id_modal_save",
- cancel: "one_f_switchmanager_staticRouteConfig_id_modal_cancel",
- remove: "one_f_switchmanager_staticRouteConfig_id_modal_remove",
- form: {
- routeName : "one_f_switchmanager_staticRouteConfig_id_modal_form_routename",
- staticRoute : "one_f_switchmanager_staticRouteConfig_id_modal_form_staticroute",
- nextHop : "one_f_switchmanager_staticRouteConfig_id_modal_form_nexthop",
+ id: {
+ dashlet: {
+ add: "one_f_switchmanager_staticRouteConfig_id_dashlet_add",
+ remove: "one_f_switchmanager_staticRouteConfig_id_dashlet_remove",
+ datagrid: "one_f_switchmanager_staticRouteConfig_id_dashlet_datagrid",
+ selectAll: "one_f_switchmanager_staticRouteConfig_id_dashlet_selectAll"
+ },
+ modal: {
+ modal: "one_f_switchmanager_staticRouteConfig_id_modal_modal",
+ save: "one_f_switchmanager_staticRouteConfig_id_modal_save",
+ cancel: "one_f_switchmanager_staticRouteConfig_id_modal_cancel",
+ remove: "one_f_switchmanager_staticRouteConfig_id_modal_remove",
+ form: {
+ routeName : "one_f_switchmanager_staticRouteConfig_id_modal_form_routename",
+ staticRoute : "one_f_switchmanager_staticRouteConfig_id_modal_form_staticroute",
+ nextHop : "one_f_switchmanager_staticRouteConfig_id_modal_form_nexthop",
+ }
+ }
+ },
+ dashlet: function($dashlet) {
+ one.lib.dashlet.empty($dashlet);
+ var url = one.f.switchmanager.rootUrl + "/staticRoutes";
+ one.f.switchmanager.staticRouteConfig.ajax.main(url, {}, function(content) {
+
+ if (content.privilege === 'WRITE') {
+ // Add static route button
+ var button = one.lib.dashlet.button.single("Add Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.add, "btn-primary", "btn-mini");
+ var $button = one.lib.dashlet.button.button(button);
+ $button.click(function() {
+ var $modal = one.f.switchmanager.staticRouteConfig.modal.initialize();
+ $modal.modal();
+ });
+ $dashlet.append(one.lib.dashlet.header(one.f.dashlet.staticRouteConfig.name));
+ $dashlet.append($button);
+
+ // Delete static route button
+ var button = one.lib.dashlet.button.single("Remove Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.remove, "btn-danger", "btn-mini");
+ var $button = one.lib.dashlet.button.button(button);
+ $button.click(function() {
+ var routesToDelete = [];
+ var checkedCheckBoxes = $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find("tbody input:checked");
+ checkedCheckBoxes.each(function(index, value) {
+ routesToDelete.push(checkedCheckBoxes[index].id);
+ });
+ if (checkedCheckBoxes.size() === 0) {
+ return false;
+ }
+ one.f.switchmanager.staticRouteConfig.modal.removeMultiple.dialog(routesToDelete);
+ });
+ $dashlet.append($button);
+ }
+ var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid, {
+ searchable: true,
+ filterable: false,
+ pagination: true,
+ flexibleRowsPerPage: true
+ }, "table-striped table-condensed");
+ $dashlet.append($gridHTML);
+ var dataSource = one.f.switchmanager.staticRouteConfig.data.staticRouteConfigGrid(content);
+ $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
+ .on("loaded", function() {
+ $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).click(function() {
+ $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
+ $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).is(':checked'));
+ });
+ $(".staticRoute").click(function(e){
+ if (!$('.staticRoute[type=checkbox]:not(:checked)').length) {
+ $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
+ .prop("checked",
+ true);
+ } else {
+ $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
+ .prop("checked",
+ false);
}
+ e.stopPropagation();
+ });
+ });
+ });
+ },
+ // device ajax calls
+ ajax : {
+ main : function(url, requestData, callback) {
+ $.getJSON(url, requestData, function(data) {
+ callback(data);
+ });
+ }
+ },
+ registry: {},
+ modal : {
+ initialize: function() {
+ var h3 = "Add Static Route";
+ var footer = one.f.switchmanager.staticRouteConfig.modal.footer();
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, "", footer);
+ // bind save button
+ $('#' + one.f.switchmanager.staticRouteConfig.id.modal.save, $modal).click(function() {
+ one.f.switchmanager.staticRouteConfig.modal.save($modal);
+ });
+ var $body = one.f.switchmanager.staticRouteConfig.modal.body();
+ one.lib.modal.inject.body($modal, $body);
+ return $modal;
+ },
+ save: function($modal) {
+ var result = {};
+ result['routeName'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.routeName, $modal).val();
+ result['staticRoute'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute, $modal).val();
+ result['nextHop'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop, $modal).val();
+ one.f.switchmanager.staticRouteConfig.modal.ajax.staticRouteConfig(result, function(response) {
+ if(response.status == true) {
+ $modal.modal('hide');
+ // refresh dashlet by passing dashlet div as param
+ one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
+ } else {
+ // TODO: Show error message in a error message label instead.
+ alert(response.message);
}
+ });
},
- dashlet: function($dashlet) {
- one.lib.dashlet.empty($dashlet);
- var url = one.f.switchmanager.rootUrl + "/staticRoutes";
- one.f.switchmanager.staticRouteConfig.ajax.main(url, {}, function(content) {
-
- if (content.privilege === 'WRITE') {
- // Add static route button
- var button = one.lib.dashlet.button.single("Add Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.add, "btn-primary", "btn-mini");
- var $button = one.lib.dashlet.button.button(button);
- $button.click(function() {
- var $modal = one.f.switchmanager.staticRouteConfig.modal.initialize();
- $modal.modal();
- });
- $dashlet.append(one.lib.dashlet.header(one.f.dashlet.staticRouteConfig.name));
- $dashlet.append($button);
-
- // Delete static route button
- var button = one.lib.dashlet.button.single("Remove Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.remove, "btn-danger", "btn-mini");
- var $button = one.lib.dashlet.button.button(button);
- $button.click(function() {
- var routesToDelete = [];
- var checkedCheckBoxes = $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find("tbody input:checked");
- checkedCheckBoxes.each(function(index, value) {
- routesToDelete.push(checkedCheckBoxes[index].id);
- });
- if (checkedCheckBoxes.size() === 0) {
- return false;
- }
- one.f.switchmanager.staticRouteConfig.modal.removeMultiple.dialog(routesToDelete);
- });
- $dashlet.append($button);
- }
- var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid, {
- searchable: true,
- filterable: false,
- pagination: true,
- flexibleRowsPerPage: true
- }, "table-striped table-condensed");
- $dashlet.append($gridHTML);
- var dataSource = one.f.switchmanager.staticRouteConfig.data.staticRouteConfigGrid(content);
- $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
- .on("loaded", function() {
- $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).click(function() {
- $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
- $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).is(':checked'));
- });
- $(".staticRoute").click(function(e){
- if (!$('.staticRoute[type=checkbox]:not(:checked)').length) {
- $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
- .prop("checked",
- true);
- } else {
- $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
- .prop("checked",
- false);
- }
- e.stopPropagation();
- });
- });
+ body: function() {
+ var $form = $(document.createElement('form'));
+ var $fieldset = $(document.createElement('fieldset'));
+ // static route name
+ var $label = one.lib.form.label("Name");
+ var $input = one.lib.form.input("Name");
+ $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.routeName);
+ $fieldset.append($label).append($input);
+ // static route IP Mask
+ var $label = one.lib.form.label("Static Route");
+ var $input = one.lib.form.input("Static Route");
+ var $help = one.lib.form.help('Example: 53.55.0.0/16');
+ $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute);
+ $fieldset.append($label).append($input).append($help);
+ // static route IP Mask
+ var $label = one.lib.form.label("Next Hop");
+ var $input = one.lib.form.input("Next Hop");
+ var $help = one.lib.form.help('Example: 192.168.10.254');
+ $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop);
+ $fieldset.append($label).append($input).append($help);
+ // return
+ $form.append($fieldset);
+ return $form;
+ },
+ ajax: {
+ staticRouteConfig: function(requestData, callback) {
+ $.getJSON(one.f.switchmanager.rootUrl + "/staticRoute/add", requestData, function(data) {
+ callback(data);
});
+ }
},
- // device ajax calls
- ajax : {
- main : function(url, requestData, callback) {
- $.getJSON(url, requestData, function(data) {
- callback(data);
- });
- }
+ data : {
+
},
- registry: {},
- modal : {
- initialize: function() {
- var h3 = "Add Static Route";
- var footer = one.f.switchmanager.staticRouteConfig.modal.footer();
- var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, "", footer);
- // bind save button
- $('#' + one.f.switchmanager.staticRouteConfig.id.modal.save, $modal).click(function() {
- one.f.switchmanager.staticRouteConfig.modal.save($modal);
+ footer : function() {
+ var footer = [];
+ var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.staticRouteConfig.id.modal.save, "btn-primary", "");
+ var $saveButton = one.lib.dashlet.button.button(saveButton);
+ footer.push($saveButton);
+ return footer;
+ },
+ removeMultiple: {
+ dialog: function(routesToDelete) {
+ var h3 = 'Remove Static Route';
+
+ var footer = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.footer();
+ var $body = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.body(routesToDelete);
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, $body, footer);
+
+ // bind close button
+ $('#'+one.f.switchmanager.staticRouteConfig.id.modal.cancel, $modal).click(function() {
+ $modal.modal('hide');
+ });
+
+ // bind remove rule button
+ $('#'+one.f.switchmanager.staticRouteConfig.id.modal.remove, $modal).click(this, function(e) {
+ if (routesToDelete.length > 0) {
+ var requestData = {};
+ requestData["routesToDelete"] = routesToDelete.toString();
+ var url = one.f.switchmanager.rootUrl + "/staticRoute/delete";
+ one.f.switchmanager.staticRouteConfig.ajax.main(url, requestData, function(response) {
+ $modal.modal('hide');
+ if (response.status == true) {
+ // refresh dashlet by passing dashlet div as param
+ one.lib.alert("Static Route(s) successfully removed");
+ } else {
+ alert(response.message);
+ }
+ one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
});
- var $body = one.f.switchmanager.staticRouteConfig.modal.body();
- one.lib.modal.inject.body($modal, $body);
- return $modal;
- },
- save: function($modal) {
- var result = {};
- result['routeName'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.routeName, $modal).val();
- result['staticRoute'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute, $modal).val();
- result['nextHop'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop, $modal).val();
- one.f.switchmanager.staticRouteConfig.modal.ajax.staticRouteConfig(result, function(response) {
- if(response.status == true) {
- $modal.modal('hide');
- // refresh dashlet by passing dashlet div as param
- one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
- } else {
- // TODO: Show error message in a error message label instead.
- alert(response.message);
- }
- });
- },
- body: function() {
- var $form = $(document.createElement('form'));
- var $fieldset = $(document.createElement('fieldset'));
- // static route name
- var $label = one.lib.form.label("Name");
- var $input = one.lib.form.input("Name");
- $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.routeName);
- $fieldset.append($label).append($input);
- // static route IP Mask
- var $label = one.lib.form.label("Static Route");
- var $input = one.lib.form.input("Static Route");
- var $help = one.lib.form.help('Example: 53.55.0.0/16');
- $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute);
- $fieldset.append($label).append($input).append($help);
- // static route IP Mask
- var $label = one.lib.form.label("Next Hop");
- var $input = one.lib.form.input("Next Hop");
- var $help = one.lib.form.help('Example: 192.168.10.254');
- $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop);
- $fieldset.append($label).append($input).append($help);
- // return
- $form.append($fieldset);
- return $form;
- },
- ajax: {
- staticRouteConfig: function(requestData, callback) {
- $.getJSON(one.f.switchmanager.rootUrl + "/staticRoute/add", requestData, function(data) {
- callback(data);
- });
- }
- },
- data : {
-
- },
- footer : function() {
- var footer = [];
- var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.staticRouteConfig.id.modal.save, "btn-primary", "");
- var $saveButton = one.lib.dashlet.button.button(saveButton);
- footer.push($saveButton);
- return footer;
+ }
+ });
+ $modal.modal();
+ },
+ footer : function() {
+ var footer = [];
+ var remove = one.lib.dashlet.button.single('Remove Static Route',one.f.switchmanager.staticRouteConfig.id.modal.remove, 'btn-danger', '');
+ var $remove = one.lib.dashlet.button.button(remove);
+ footer.push($remove);
+
+ var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.staticRouteConfig.id.modal.cancel, '', '');
+ var $cancel = one.lib.dashlet.button.button(cancel);
+ footer.push($cancel);
+
+ return footer;
+ },
+ body : function (staticRouteList) {
+ var $p = $(document.createElement('p'));
+ var p = 'Remove the following Static Route(s)?';
+ //creata a BS label for each rule and append to list
+ $(staticRouteList).each(function(){
+ var $span = $(document.createElement('span'));
+ $span.append(this);
+ p += '<br/>' + $span[0].outerHTML;
+ });
+ $p.append(p);
+ return $p;
+ }
+ }
+ },
+ // data functions
+ data : {
+ staticRouteConfigGrid: function(data) {
+ var source = new StaticDataSource({
+ columns: [
+ {
+ property: 'selector',
+ label: "<input type='checkbox' id='"
+ +one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll+"'/>",
+ sortable: false
+ },
+ {
+ property: 'name',
+ label: 'Name',
+ sortable: true
+ },
+ {
+ property: 'staticRoute',
+ label: 'Static Route',
+ sortable: true
+ },
+ {
+ property: 'nextHop',
+ label: 'Next Hop Address',
+ sortable: true
+ }
+ ],
+ data: data.nodeData,
+ formatter: function(items) {
+ $.each(items, function(index, item) {
+ item["selector"] = '<input type="checkbox" class="staticRoute" id="' + item["name"] + '"></input>';
+ });
+
},
- removeMultiple: {
- dialog: function(routesToDelete) {
- var h3 = 'Remove Static Route';
-
- var footer = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.footer();
- var $body = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.body(routesToDelete);
- var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, $body, footer);
-
- // bind close button
- $('#'+one.f.switchmanager.staticRouteConfig.id.modal.cancel, $modal).click(function() {
- $modal.modal('hide');
- });
-
- // bind remove rule button
- $('#'+one.f.switchmanager.staticRouteConfig.id.modal.remove, $modal).click(this, function(e) {
- if (routesToDelete.length > 0) {
- var requestData = {};
- requestData["routesToDelete"] = routesToDelete.toString();
- var url = one.f.switchmanager.rootUrl + "/staticRoute/delete";
- one.f.switchmanager.staticRouteConfig.ajax.main(url, requestData, function(response) {
- $modal.modal('hide');
- if (response.status == true) {
- // refresh dashlet by passing dashlet div as param
- one.lib.alert("Static Route(s) successfully removed");
- } else {
- alert(response.message);
- }
- one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
- });
- }
- });
- $modal.modal();
- },
- footer : function() {
- var footer = [];
- var remove = one.lib.dashlet.button.single('Remove Static Route',one.f.switchmanager.staticRouteConfig.id.modal.remove, 'btn-danger', '');
- var $remove = one.lib.dashlet.button.button(remove);
- footer.push($remove);
-
- var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.staticRouteConfig.id.modal.cancel, '', '');
- var $cancel = one.lib.dashlet.button.button(cancel);
- footer.push($cancel);
-
- return footer;
- },
- body : function (staticRouteList) {
- var $p = $(document.createElement('p'));
- var p = 'Remove the following Static Route(s)?';
- //creata a BS label for each rule and append to list
- $(staticRouteList).each(function(){
- var $span = $(document.createElement('span'));
- $span.append(this);
- p += '<br/>' + $span[0].outerHTML;
- });
- $p.append(p);
- return $p;
- }
- }
+ delay: 0
+ });
+ return source;
},
- // data functions
- data : {
- staticRouteConfigGrid: function(data) {
- var source = new StaticDataSource({
- columns: [
- {
- property: 'selector',
- label: "<input type='checkbox' id='"
- +one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll+"'/>",
- sortable: false
- },
- {
- property: 'name',
- label: 'Name',
- sortable: true
- },
- {
- property: 'staticRoute',
- label: 'Static Route',
- sortable: true
- },
- {
- property: 'nextHop',
- label: 'Next Hop Address',
- sortable: true
- }
- ],
- data: data.nodeData,
- formatter: function(items) {
- $.each(items, function(index, item) {
- item["selector"] = '<input type="checkbox" class="staticRoute" id="' + item["name"] + '"></input>';
- });
-
- },
- delay: 0
- });
- return source;
- },
- staticRouteConfig : function(data) {
- var result = [];
- $.each(data.nodeData, function(key, value) {
- var tr = {};
- // fill up all the td's
- var entry = [];
- var checkbox = document.createElement("input");
- checkbox.setAttribute("type", "checkbox");
- checkbox.setAttribute("id", value["name"]);
- entry.push(checkbox);
- entry.push(value["name"]);
- entry.push(value["staticRoute"]);
- entry.push(value["nextHop"]);
- tr.entry = entry;
- result.push(tr);
- });
- return result;
- }
+ staticRouteConfig : function(data) {
+ var result = [];
+ $.each(data.nodeData, function(key, value) {
+ var tr = {};
+ // fill up all the td's
+ var entry = [];
+ var checkbox = document.createElement("input");
+ checkbox.setAttribute("type", "checkbox");
+ checkbox.setAttribute("id", value["name"]);
+ entry.push(checkbox);
+ entry.push(value["name"]);
+ entry.push(value["staticRoute"]);
+ entry.push(value["nextHop"]);
+ tr.entry = entry;
+ result.push(tr);
+ });
+ return result;
}
+ }
}
one.f.switchmanager.spanPortConfig = {
- id: {
- dashlet: {
- add: "one_f_switchmanager_spanPortConfig_id_dashlet_add",
- remove: "one_f_switchmanager_spanPortConfig_id_dashlet_remove",
- datagrid: "one_f_switchmanager_spanPortConfig_id_dashlet_datagrid",
- selectAllFlows: "one_f_switchmanager_spanPortConfig_id_dashlet_selectAllFlows"
- },
- modal: {
- modal: "one_f_switchmanager_spanPortConfig_id_modal_modal",
- save: "one_f_switchmanager_spanPortConfig_id_modal_save",
- cancel: "one_f_switchmanager_spanPortConfig_id_modal_cancel",
- remove: "one_f_switchmanager_spanPortConfig_id_modal_remove",
- form: {
- name : "one_f_switchmanager_spanPortConfig_id_modal_form_name",
- nodes : "one_f_switchmanager_spanPortConfig_id_modal_form_nodes",
- port : "one_f_switchmanager_spanPortConfig_id_modal_form_port",
+ id: {
+ dashlet: {
+ add: "one_f_switchmanager_spanPortConfig_id_dashlet_add",
+ remove: "one_f_switchmanager_spanPortConfig_id_dashlet_remove",
+ datagrid: "one_f_switchmanager_spanPortConfig_id_dashlet_datagrid",
+ selectAllFlows: "one_f_switchmanager_spanPortConfig_id_dashlet_selectAllFlows"
+ },
+ modal: {
+ modal: "one_f_switchmanager_spanPortConfig_id_modal_modal",
+ save: "one_f_switchmanager_spanPortConfig_id_modal_save",
+ cancel: "one_f_switchmanager_spanPortConfig_id_modal_cancel",
+ remove: "one_f_switchmanager_spanPortConfig_id_modal_remove",
+ form: {
+ name : "one_f_switchmanager_spanPortConfig_id_modal_form_name",
+ nodes : "one_f_switchmanager_spanPortConfig_id_modal_form_nodes",
+ port : "one_f_switchmanager_spanPortConfig_id_modal_form_port",
+ }
+ }
+ },
+ dashlet: function($dashlet) {
+ one.lib.dashlet.empty($dashlet);
+
+ //populate table in dashlet
+ var url = one.f.switchmanager.rootUrl + "/spanPorts";
+ one.f.switchmanager.spanPortConfig.ajax.main(url, {}, function(content) {
+
+ if (content.privilege === 'WRITE') {
+
+ // Add span port button
+ var button = one.lib.dashlet.button.single("Add SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.add, "btn-primary", "btn-mini");
+ var $button = one.lib.dashlet.button.button(button);
+
+ $button.click(function() {
+ var $modal = one.f.switchmanager.spanPortConfig.modal.initialize();
+ $modal.modal();
+ });
+ $dashlet.append(one.lib.dashlet.header(one.f.dashlet.spanPortConfig.name));
+ $dashlet.append($button);
+
+ // Delete span port button
+ var button = one.lib.dashlet.button.single("Remove SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.remove, "btn-danger", "btn-mini");
+ var $button = one.lib.dashlet.button.button(button);
+ $button.click(function() {
+ var spanPortsToDelete = [];
+ var checkedCheckBoxes = $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find("tbody input:checked");
+
+ if (checkedCheckBoxes.size() === 0) {
+ return false;
+ }
+ checkedCheckBoxes.each(function(index, value) {
+ var spanPortObj = {};
+ spanPortObj['spanPortJson'] = decodeURIComponent(checkedCheckBoxes[index].getAttribute("spanPort"));
+ spanPortObj['spanPortNodeName'] = checkedCheckBoxes[index].getAttribute("spanPortNode");
+ spanPortObj['spanPortPortName'] = checkedCheckBoxes[index].getAttribute("spanPortPort");
+
+ spanPortsToDelete.push(spanPortObj);
+ });
+ one.f.switchmanager.spanPortConfig.modal.removeMultiple.dialog(spanPortsToDelete);
+ });
+ $dashlet.append($button);
+ }
+ var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.spanPortConfig.id.dashlet.datagrid, {
+ searchable: true,
+ filterable: false,
+ pagination: true,
+ flexibleRowsPerPage: true
+ }, "table-striped table-condensed");
+ $dashlet.append($gridHTML);
+ var dataSource = one.f.switchmanager.spanPortConfig.data.spanPortConfigGrid(content);
+ $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
+ .on("loaded", function() {
+ $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).click(function() {
+ $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
+ $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).is(':checked'));
+ });
+ $(".spanPortConfig").click(function(e){
+ if (!$('.spanPortConfig[type=checkbox]:not(:checked)').length) {
+ $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
+ .prop("checked",
+ true);
+ } else {
+ $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
+ .prop("checked",
+ false);
}
- }
+ e.stopPropagation();
+ });
+ });
+ });
+ },
+ // device ajax calls
+ ajax : {
+ main : function(url, requestData, callback) {
+ $.getJSON(url, requestData, function(data) {
+ callback(data);
+ });
+ }
+ },
+ registry: {},
+ modal : {
+ initialize: function() {
+ var h3 = "Add SPAN Port";
+ var footer = one.f.switchmanager.spanPortConfig.modal.footer();
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, "", footer);
+ // bind save button
+ $('#' + one.f.switchmanager.spanPortConfig.id.modal.save, $modal).click(function() {
+ one.f.switchmanager.spanPortConfig.modal.save($modal);
+ });
+
+ one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
+ var $body = one.f.switchmanager.spanPortConfig.modal.body(nodes, nodeports);
+ one.lib.modal.inject.body($modal, $body);
+ });
+ return $modal;
},
- dashlet: function($dashlet) {
- one.lib.dashlet.empty($dashlet);
-
- //populate table in dashlet
- var url = one.f.switchmanager.rootUrl + "/spanPorts";
- one.f.switchmanager.spanPortConfig.ajax.main(url, {}, function(content) {
-
- if (content.privilege === 'WRITE') {
-
- // Add span port button
- var button = one.lib.dashlet.button.single("Add SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.add, "btn-primary", "btn-mini");
- var $button = one.lib.dashlet.button.button(button);
-
- $button.click(function() {
- var $modal = one.f.switchmanager.spanPortConfig.modal.initialize();
- $modal.modal();
- });
- $dashlet.append(one.lib.dashlet.header(one.f.dashlet.spanPortConfig.name));
- $dashlet.append($button);
-
- // Delete span port button
- var button = one.lib.dashlet.button.single("Remove SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.remove, "btn-danger", "btn-mini");
- var $button = one.lib.dashlet.button.button(button);
- $button.click(function() {
- var spanPortsToDelete = [];
- var checkedCheckBoxes = $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find("tbody input:checked");
-
- if (checkedCheckBoxes.size() === 0) {
- return false;
- }
- checkedCheckBoxes.each(function(index, value) {
- var spanPortObj = {};
- spanPortObj['spanPortJson'] = decodeURIComponent(checkedCheckBoxes[index].getAttribute("spanPort"));
- spanPortObj['spanPortNodeName'] = checkedCheckBoxes[index].getAttribute("spanPortNode");
- spanPortObj['spanPortPortName'] = checkedCheckBoxes[index].getAttribute("spanPortPort");
-
- spanPortsToDelete.push(spanPortObj);
- });
- one.f.switchmanager.spanPortConfig.modal.removeMultiple.dialog(spanPortsToDelete);
- });
- $dashlet.append($button);
+ save: function($modal) {
+ var result = {};
+ result['nodeId'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.nodes, $modal).val();
+ result['spanPort'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.port, $modal).val();
+ one.f.switchmanager.spanPortConfig.modal.ajax.saveSpanPortConfig(result,
+ function(response) {
+ if(response.status == true) {
+ $modal.modal('hide');
+ one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
+ } else {
+ alert(response.message);
}
- var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.spanPortConfig.id.dashlet.datagrid, {
- searchable: true,
- filterable: false,
- pagination: true,
- flexibleRowsPerPage: true
- }, "table-striped table-condensed");
- $dashlet.append($gridHTML);
- var dataSource = one.f.switchmanager.spanPortConfig.data.spanPortConfigGrid(content);
- $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
- .on("loaded", function() {
- $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).click(function() {
- $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
- $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).is(':checked'));
- });
- $(".spanPortConfig").click(function(e){
- if (!$('.spanPortConfig[type=checkbox]:not(:checked)').length) {
- $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
- .prop("checked",
- true);
- } else {
- $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
- .prop("checked",
- false);
- }
- e.stopPropagation();
- });
- });
+
+ });
+ },
+ body: function(nodes, nodeports) {
+ var $form = $(document.createElement('form'));
+ var $fieldset = $(document.createElement('fieldset'));
+ // node
+ var $label = one.lib.form.label("Node");
+ var $select = one.lib.form.select.create(nodes);
+ one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
+ $select.val($select.find("option:first").val());
+ $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.nodes);
+
+ // bind onchange
+ $select.change(function() {
+ // retrieve port value
+ var nodeId = $(this).find('option:selected').attr('value');
+ one.f.switchmanager.spanPortConfig.registry['currentNode'] = nodeId;
+ var $ports = $('#'+one.f.switchmanager.spanPortConfig.id.modal.form.port);
+ var ports = one.f.switchmanager.spanPortConfig.registry['nodePorts'][nodeId]
+ var options = {};
+ $(ports).each(function(idx, val) {
+ options[val.internalPortName] = val.portName+' ('+val.portId+')';
+ });
+ one.lib.form.select.inject($ports, options);
+ one.lib.form.select.prepend($ports, {'':'Please Select a Port'});
+ $ports.val($ports.find('option:first').val());
+ });
+
+ $fieldset.append($label).append($select);
+ // input port
+ var $label = one.lib.form.label("Input Port");
+ var $select = one.lib.form.select.create();
+ one.lib.form.select.prepend($select, {'':'None'});
+ $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
+ $select.val($select.find('option:first').val());
+ $fieldset.append($label).append($select);
+
+ // return
+ $form.append($fieldset);
+ return $form;
+ },
+ ajax: {
+ nodes: function(callback) {
+ $.getJSON(one.f.switchmanager.rootUrl + "/nodeports", function(data) {
+ var nodes = {};
+ var nodePorts = {};
+ $(data).each(function(index, node) {
+ nodes[node.nodeId] = node.nodeName;
+ nodePorts[node.nodeId] = node.nodePorts;
+ });
+ one.f.switchmanager.spanPortConfig.registry['nodePorts'] = nodePorts;
+ callback(nodes, nodePorts);
});
+ },
+ saveSpanPortConfig: function(requestData, callback) {
+ var resource = {};
+ resource["jsonData"] = JSON.stringify(requestData);
+ $.getJSON(one.f.switchmanager.rootUrl + "/spanPorts/add", resource, function(data) {
+ callback(data);
+ });
+ }
},
- // device ajax calls
- ajax : {
- main : function(url, requestData, callback) {
- $.getJSON(url, requestData, function(data) {
- callback(data);
- });
- }
+ footer : function() {
+ var footer = [];
+ var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.spanPortConfig.id.modal.save, "btn-primary", "");
+ var $saveButton = one.lib.dashlet.button.button(saveButton);
+ footer.push($saveButton);
+ return footer;
},
- registry: {},
- modal : {
- initialize: function() {
- var h3 = "Add SPAN Port";
- var footer = one.f.switchmanager.spanPortConfig.modal.footer();
- var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, "", footer);
- // bind save button
- $('#' + one.f.switchmanager.spanPortConfig.id.modal.save, $modal).click(function() {
- one.f.switchmanager.spanPortConfig.modal.save($modal);
- });
+ removeMultiple: {
+ dialog: function(spanPortsToDelete) {
+ var h3 = 'Remove SPAN Port';
- one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
- var $body = one.f.switchmanager.spanPortConfig.modal.body(nodes, nodeports);
- one.lib.modal.inject.body($modal, $body);
- });
- return $modal;
- },
- save: function($modal) {
- var result = {};
- result['nodeId'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.nodes, $modal).val();
- result['spanPort'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.port, $modal).val();
- one.f.switchmanager.spanPortConfig.modal.ajax.saveSpanPortConfig(result,
- function(response) {
- if(response.status == true) {
- $modal.modal('hide');
- one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
- } else {
- alert(response.message);
- }
-
- });
- },
- body: function(nodes, nodeports) {
- var $form = $(document.createElement('form'));
- var $fieldset = $(document.createElement('fieldset'));
- // node
- var $label = one.lib.form.label("Node");
- var $select = one.lib.form.select.create(nodes);
- one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
- $select.val($select.find("option:first").val());
- $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.nodes);
-
- // bind onchange
- $select.change(function() {
- // retrieve port value
- var nodeId = $(this).find('option:selected').attr('value');
- one.f.switchmanager.spanPortConfig.registry['currentNode'] = nodeId;
- var $ports = $('#'+one.f.switchmanager.spanPortConfig.id.modal.form.port);
- var ports = one.f.switchmanager.spanPortConfig.registry['nodePorts'][nodeId]
- var options = {};
- $(ports).each(function(idx, val) {
- options[val.internalPortName] = val.portName+' ('+val.portId+')';
- });
- one.lib.form.select.inject($ports, options);
- one.lib.form.select.prepend($ports, {'':'Please Select a Port'});
- $ports.val($ports.find('option:first').val());
- });
+ var footer = one.f.switchmanager.spanPortConfig.modal.removeMultiple.footer();
+ var $body = one.f.switchmanager.spanPortConfig.modal.removeMultiple.body(spanPortsToDelete);
+ var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, $body, footer);
- $fieldset.append($label).append($select);
- // input port
- var $label = one.lib.form.label("Input Port");
- var $select = one.lib.form.select.create();
- one.lib.form.select.prepend($select, {'':'None'});
- $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
- $select.val($select.find('option:first').val());
- $fieldset.append($label).append($select);
-
- // return
- $form.append($fieldset);
- return $form;
- },
- ajax: {
- nodes: function(callback) {
- $.getJSON(one.f.switchmanager.rootUrl + "/nodeports", function(data) {
- var nodes = {};
- var nodePorts = {};
- $(data).each(function(index, node) {
- nodes[node.nodeId] = node.nodeName;
- nodePorts[node.nodeId] = node.nodePorts;
- });
- one.f.switchmanager.spanPortConfig.registry['nodePorts'] = nodePorts;
- callback(nodes, nodePorts);
- });
- },
- saveSpanPortConfig: function(requestData, callback) {
- var resource = {};
- resource["jsonData"] = JSON.stringify(requestData);
- $.getJSON(one.f.switchmanager.rootUrl + "/spanPorts/add", resource, function(data) {
- callback(data);
- });
- }
- },
- footer : function() {
- var footer = [];
- var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.spanPortConfig.id.modal.save, "btn-primary", "");
- var $saveButton = one.lib.dashlet.button.button(saveButton);
- footer.push($saveButton);
- return footer;
- },
- removeMultiple: {
- dialog: function(spanPortsToDelete) {
- var h3 = 'Remove SPAN Port';
-
- var footer = one.f.switchmanager.spanPortConfig.modal.removeMultiple.footer();
- var $body = one.f.switchmanager.spanPortConfig.modal.removeMultiple.body(spanPortsToDelete);
- var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, $body, footer);
-
- // bind close button
- $('#'+one.f.switchmanager.spanPortConfig.id.modal.cancel, $modal).click(function() {
- $modal.modal('hide');
- });
-
- // bind remove rule button
- $('#'+one.f.switchmanager.spanPortConfig.id.modal.remove, $modal).click(this, function(e) {
- var requestData = {};
- var spanPorts = [];
- $(spanPortsToDelete).each(function(index, spanPort) {
- spanPorts.push(JSON.parse(spanPort.spanPortJson));
- });
- requestData["spanPortsToDelete"] = JSON.stringify(spanPorts);
-
- var url = one.f.switchmanager.rootUrl + "/spanPorts/delete";
- one.f.switchmanager.spanPortConfig.ajax.main(url, requestData, function(response) {
- $modal.modal('hide');
- if (response.status == true) {
- // refresh dashlet by passing dashlet div as param
- one.lib.alert("Span Port(s) successfully removed");
- } else {
- alert(response.message);
- }
- one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
- });
- });
- $modal.modal();
- },
- footer : function() {
- var footer = [];
- var remove = one.lib.dashlet.button.single('Remove SPAN Port',one.f.switchmanager.spanPortConfig.id.modal.remove, 'btn-danger', '');
- var $remove = one.lib.dashlet.button.button(remove);
- footer.push($remove);
-
- var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.spanPortConfig.id.modal.cancel, '', '');
- var $cancel = one.lib.dashlet.button.button(cancel);
- footer.push($cancel);
-
- return footer;
- },
- body : function (spanPortToDelete) {
- var $p = $(document.createElement('p'));
- var p = 'Remove the following Span Port(s)?';
- //creata a BS label for each rule and append to list
-
- $(spanPortToDelete).each(function(index, spanPortItem) {
- var $span = $(document.createElement('span'));
- $span.append(this.spanPortNodeName+"-"+this.spanPortPortName);
- p += '<br/>' + $span[0].outerHTML;
- });
- $p.append(p);
- return $p;
+ // bind close button
+ $('#'+one.f.switchmanager.spanPortConfig.id.modal.cancel, $modal).click(function() {
+ $modal.modal('hide');
+ });
+
+ // bind remove rule button
+ $('#'+one.f.switchmanager.spanPortConfig.id.modal.remove, $modal).click(this, function(e) {
+ var requestData = {};
+ var spanPorts = [];
+ $(spanPortsToDelete).each(function(index, spanPort) {
+ spanPorts.push(JSON.parse(spanPort.spanPortJson));
+ });
+ requestData["spanPortsToDelete"] = JSON.stringify(spanPorts);
+
+ var url = one.f.switchmanager.rootUrl + "/spanPorts/delete";
+ one.f.switchmanager.spanPortConfig.ajax.main(url, requestData, function(response) {
+ $modal.modal('hide');
+ if (response.status == true) {
+ // refresh dashlet by passing dashlet div as param
+ one.lib.alert("Span Port(s) successfully removed");
+ } else {
+ alert(response.message);
}
- }
+ one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
+ });
+ });
+ $modal.modal();
+ },
+ footer : function() {
+ var footer = [];
+ var remove = one.lib.dashlet.button.single('Remove SPAN Port',one.f.switchmanager.spanPortConfig.id.modal.remove, 'btn-danger', '');
+ var $remove = one.lib.dashlet.button.button(remove);
+ footer.push($remove);
+
+ var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.spanPortConfig.id.modal.cancel, '', '');
+ var $cancel = one.lib.dashlet.button.button(cancel);
+ footer.push($cancel);
+
+ return footer;
+ },
+ body : function (spanPortToDelete) {
+ var $p = $(document.createElement('p'));
+ var p = 'Remove the following Span Port(s)?';
+ //creata a BS label for each rule and append to list
+
+ $(spanPortToDelete).each(function(index, spanPortItem) {
+ var $span = $(document.createElement('span'));
+ $span.append(this.spanPortNodeName+"-"+this.spanPortPortName);
+ p += '<br/>' + $span[0].outerHTML;
+ });
+ $p.append(p);
+ return $p;
+ }
+ }
+ },
+ // data functions
+ data : {
+ spanPortConfigGrid: function(data) {
+ var source = new StaticDataSource({
+ columns: [
+ {
+ property: 'selector',
+ label: "<input type='checkbox' id='"
+ +one.f.switchmanager.spanPortConfig.id.dashlet.selectAll+"'/>",
+ sortable: false
+ },
+ {
+ property: 'nodeName',
+ label: 'Node',
+ sortable: true
+ },
+ {
+ property: 'spanPortName',
+ label: 'SPAN Port',
+ sortable: true
+ },
+ ],
+ data: data.nodeData,
+ formatter: function(items) {
+ $.each(items, function(index, item) {
+ item["selector"] = '<input type="checkbox" class="spanPortConfig" spanPort=' + encodeURIComponent(item["json"]) + ' spanPortNode="' + item["nodeName"] + '" spanPortPort="' + item["spanPortName"] + '"></input>';
+ });
+ },
+ delay: 0
+ });
+ return source;
},
- // data functions
- data : {
- spanPortConfigGrid: function(data) {
- var source = new StaticDataSource({
- columns: [
- {
- property: 'selector',
- label: "<input type='checkbox' id='"
- +one.f.switchmanager.spanPortConfig.id.dashlet.selectAll+"'/>",
- sortable: false
- },
- {
- property: 'nodeName',
- label: 'Node',
- sortable: true
- },
- {
- property: 'spanPortName',
- label: 'SPAN Port',
- sortable: true
- },
- ],
- data: data.nodeData,
- formatter: function(items) {
- $.each(items, function(index, item) {
- item["selector"] = '<input type="checkbox" class="spanPortConfig" spanPort=' + encodeURIComponent(item["json"]) + ' spanPortNode="' + item["nodeName"] + '" spanPortPort="' + item["spanPortName"] + '"></input>';
- });
- },
- delay: 0
- });
- return source;
- },
- devices : function(data) {
- var result = [];
- $.each(data.nodeData, function(key, value) {
- var tr = {};
- // fill up all the td's
- var entry = [];
- var checkbox = document.createElement("input");
- checkbox.setAttribute("type", "checkbox");
- checkbox.spanPort = value.json;
- entry.push(checkbox);
- entry.push(value["nodeName"]);
- entry.push(value["spanPort"]);
- tr.entry = entry;
- result.push(tr);
- });
- return result;
+ devices : function(data) {
+ var result = [];
+ $.each(data.nodeData, function(key, value) {
+ var tr = {};
+ // fill up all the td's
+ var entry = [];
+ var checkbox = document.createElement("input");
+ checkbox.setAttribute("type", "checkbox");
+ checkbox.spanPort = value.json;
+ entry.push(checkbox);
+ entry.push(value["nodeName"]);
+ entry.push(value["spanPort"]);
+ tr.entry = entry;
+ result.push(tr);
+ });
+ return result;
+ }
+ }
+}
+
+one.f.connection = {
+ id : { // one.f.connection.id
+ datagrid : 'one-f-connection-id-datagrid',
+ add : 'one-f-connection-id-add'
+ },
+ dashlet: function($dashlet) {
+ one.lib.dashlet.empty($dashlet);
+ // heading
+ $dashlet.append(one.lib.dashlet.header(one.f.dashlet.connection.name));
+ // add button
+ var add = one.lib.dashlet.button.single('Add Node', one.f.connection.id.add, 'btn-primary', 'btn-mini');
+ var $add = one.lib.dashlet.button.button(add);
+ $add.click(function() {
+ one.f.connection.add.initialize();
+ });
+ $dashlet.append($add);
+ // load table
+ var url = one.f.switchmanager.rootUrl+'/connect/nodes';
+ $.getJSON(url, function(data) {
+ var $gridHTML = one.lib.dashlet.datagrid.init(one.f.connection.id.datagrid, {
+ searchable: true,
+ filterable: false,
+ pagination: true,
+ flexibleRowsPerPage: true
+ }, 'table-striped table-condensed table-cursor');
+ $dashlet.append($gridHTML);
+ var dataSource = one.f.connection.data(data);
+ $('#'+one.f.connection.id.datagrid, $dashlet).datagrid({dataSource:dataSource})
+ .on('loaded', function() {
+ $(this).find('tbody tr').click(function() {
+ var nodeId = $(this).find('.nodeId').text();
+ var nodeType = $(this).find('.nodeType').text();
+ var nodeName = $(this).find('.nodeName').text();
+ one.f.connection.remove.initialize(nodeId, nodeName, nodeType);
+ });
+ });
+ });
+ },
+ data : function(data) {
+ var source = new StaticDataSource({
+ columns: [
+ {
+ property: 'nodeName',
+ label: 'Node',
+ sortable: true
+ }
+ ],
+ data: data,
+ formatter: function(items) {
+ $.each(items, function(index, item) {
+ var $nodeId = $(document.createElement('span'));
+ $nodeId.css('display', 'none');
+ var $nodeType = $nodeId.clone();
+ var $nodeName = $nodeId.clone();
+ $nodeId.append(item.nodeId).addClass('nodeId');
+ $nodeType.append(item.nodeType).addClass('nodeType');
+ $nodeName.append(item.nodeName).addClass('nodeName');
+ item.nodeName += $nodeId[0].outerHTML+$nodeType[0].outerHTML+$nodeName[0].outerHTML;
+ });
+ },
+ delay: 0
+ });
+ return source;
+ },
+ add : {
+ id : { // one.f.connection.add.id
+ modal : 'one-f-connection-add-id-modal',
+ add : 'one-f-connection-add-id-add',
+ cancel : 'one-f-connection-add-id-cancel',
+ form : {
+ nodeId : 'one-f-connection-add-id-form-nodeId',
+ ipAddress : 'one-f-connection-add-id-form-ipAddress',
+ port : 'one-f-connection-add-id-form-port',
+ nodeType : 'one-f-connection-add-id-form-nodeType'
+ }
+ },
+ initialize : function() {
+ var h3 = 'Add Node';
+ var footer = one.f.connection.add.footer();
+ var $body = one.f.connection.add.body();;
+ var $modal = one.lib.modal.spawn(one.f.connection.add.id.modal, h3, $body, footer);
+ // bind add buton
+ $('#'+one.f.connection.add.id.add, $modal).click(function() {
+ var nodeId = $('#'+one.f.connection.add.id.form.nodeId, $modal).val();
+ if (nodeId === '') {
+ alert('Please enter a node ID');
+ return false;
+ }
+ var resources = {};
+ resources.ipAddress = $('#'+one.f.connection.add.id.form.ipAddress, $modal).val();
+ if (resources.ipAddress === '') {
+ alert('Please enter an IP Address');
+ return false;
+ }
+ resources.port = $('#'+one.f.connection.add.id.form.port, $modal).val();
+ if (resources.port === '') {
+ alert('Please enter a port');
+ return false;
+ }
+ var nodeType = $('#'+one.f.connection.add.id.form.nodeType, $modal).val();
+ if (nodeType !== '') {
+ resources.nodeType = nodeType;
}
+ var url = one.f.switchmanager.rootUrl+'/connect/'+encodeURI(nodeId);
+ $.post(url, resources, function(result) {
+ if (result.success === true) {
+ $modal.modal('hide');
+ one.lib.alert(result.description);
+ } else {
+ alert(result.code+': '+result.description);
+ }
+ });
+ });
+ // bind cancel button
+ $('#'+one.f.connection.add.id.cancel, $modal).click(function() {
+ $modal.modal('hide');
+ });
+ $modal.modal();
+ },
+ body : function() {
+ var $form = $(document.createElement('form'));
+ var $fieldset = $(document.createElement('fieldset'));
+ // node id
+ var $label = one.lib.form.label('Node ID');
+ var $input = one.lib.form.input('Node ID');
+ $input.attr('id', one.f.connection.add.id.form.nodeId);
+ $fieldset.append($label).append($input);
+ // ip address
+ $label = one.lib.form.label('IP Address');
+ $input = one.lib.form.input('IP Address');
+ $input.attr('id', one.f.connection.add.id.form.ipAddress);
+ $fieldset.append($label).append($input);
+ // port
+ $label = one.lib.form.label('Port');
+ $input = one.lib.form.input('Port');
+ $input.attr('id', one.f.connection.add.id.form.port);
+ var $help = one.lib.form.help('Enter a number');
+ $fieldset.append($label).append($input).append($help);
+ // node type
+ $label = one.lib.form.label('Node Type');
+ $input = one.lib.form.input('Node Type');
+ $input.attr('id', one.f.connection.add.id.form.nodeType);
+ $help = one.lib.form.help('Optional');
+ $fieldset.append($label).append($input).append($help);
+ $form.append($fieldset);
+ return $form;
+ },
+ footer : function() {
+ var footer = [];
+ var add = one.lib.dashlet.button.single('Submit', one.f.connection.add.id.add, 'btn-primary', '');
+ var $add = one.lib.dashlet.button.button(add);
+ footer.push($add);
+ var cancel = one.lib.dashlet.button.single('Cancel', one.f.connection.add.id.cancel, '', '');
+ var $cancel = one.lib.dashlet.button.button(cancel);
+ footer.push($cancel);
+ return footer;
}
+ },
+ remove : {
+ id : { // one.f.connection.remove.id
+ modal : 'one-f-connection-remove-id-modal',
+ remove : 'one-f-connection-remove-id-remove',
+ cancel : 'one-f-connection-remove-id-cancel'
+ },
+ initialize : function(nodeId, nodeName, nodeType) {
+ var h3 = 'Remove Node';
+ var footer = one.f.connection.remove.footer();
+ var $body = one.f.connection.remove.body(nodeName);
+ var $modal = one.lib.modal.spawn(one.f.connection.remove.id.modal, h3, $body, footer);
+ // bind remove buton
+ $('#'+one.f.connection.remove.id.remove, $modal).click(function() {
+ var resources = {};
+ resources.nodeType = nodeType;
+ var url = one.f.switchmanager.rootUrl+'/disconnect/'+encodeURI(nodeId);
+ $.post(url, resources, function(result) {
+ if (result.success === true) {
+ $modal.modal('hide');
+ one.lib.alert(result.description);
+ } else {
+ alert(result.code+': '+result.description);
+ }
+ }).fail(function() { debugger; });
+ });
+ // bind cancel button
+ $('#'+one.f.connection.remove.id.cancel, $modal).click(function() {
+ $modal.modal('hide');
+ });
+ $modal.modal();
+ },
+ body : function(nodeName) {
+ var $p = $(document.createElement('p'));
+ $p.append('Remove the following node? ');
+ var $span = $(document.createElement('span'));
+ $span.addClass('label label-info');
+ $span.append(nodeName);
+ $p.append($span[0].outerHTML);
+ return $p;
+ },
+ footer : function() {
+ var footer = [];
+ var remove = one.lib.dashlet.button.single('Remove', one.f.connection.remove.id.remove, 'btn-danger', '');
+ var $remove = one.lib.dashlet.button.button(remove);
+ footer.push($remove);
+ var cancel = one.lib.dashlet.button.single('Cancel', one.f.connection.remove.id.cancel, '', '');
+ var $cancel = one.lib.dashlet.button.button(cancel);
+ footer.push($cancel);
+ return footer;
+ }
+ }
}
/** INIT **/
// populate nav tabs
$(one.f.menu.left.top).each(function(index, value) {
- var $nav = $(".nav", "#left-top");
- one.main.page.dashlet($nav, value);
+ var $nav = $(".nav", "#left-top");
+ one.main.page.dashlet($nav, value);
});
$(one.f.menu.left.bottom).each(function(index, value) {
- var $nav = $(".nav", "#left-bottom");
- one.main.page.dashlet($nav, value);
+ var $nav = $(".nav", "#left-bottom");
+ one.main.page.dashlet($nav, value);
});
$(one.f.menu.right.bottom).each(function(index, value) {
- var $nav = $(".nav", "#right-bottom");
- one.main.page.dashlet($nav, value);
+ var $nav = $(".nav", "#right-bottom");
+ one.main.page.dashlet($nav, value);
});
one.f.addPopOut = function() {
- $img1 = $(document.createElement("img"));
- $img1.attr("src", "/img/Expand16T.png");
- $img1.attr("style", "float: right;");
- $img1.hover(function() {
- $img1.css("cursor", "pointer");
+ $img1 = $(document.createElement("img"));
+ $img1.attr("src", "/img/Expand16T.png");
+ $img1.attr("style", "float: right;");
+ $img1.hover(function() {
+ $img1.css("cursor", "pointer");
+ });
+ $img1.click(function() {
+ var $modal = one.f.switchmanager.nodesLearnt.modal.initialize.popout();
+ $modal.css({
+ 'margin-left': '-45%',
+ 'margin-top': '-3%',
+ 'width':$(document).width() * 0.8,
+ 'height':$(document).height() * 0.9
});
- $img1.click(function() {
- var $modal = one.f.switchmanager.nodesLearnt.modal.initialize.popout();
- $modal.css({
- 'margin-left': '-45%',
- 'margin-top': '-3%',
- 'width':$(document).width() * 0.8,
- 'height':$(document).height() * 0.9
- });
- $(".modal-body", $modal).css({
- "max-height": $(document).height() * 0.75,
- });
- $modal.modal();
+ $(".modal-body", $modal).css({
+ "max-height": $(document).height() * 0.75,
});
- $dash1 = $($("#left-top .nav")[0]);
- $dash1.append($img1);
+ $modal.modal();
+ });
+ $dash1 = $($("#left-top .nav")[0]);
+ $dash1.append($img1);
};
one.f.addPopOut();
// bind dashlet nav
$('.dash .nav a', '#main').click(function() {
- // de/activation
- var $li = $(this).parent();
- var $ul = $li.parent();
- one.lib.nav.unfocus($ul);
- $li.addClass('active');
- // clear respective dashlet
- var $dashlet = $ul.parent().find('.dashlet');
- one.lib.dashlet.empty($dashlet);
+ // de/activation
+ var $li = $(this).parent();
+ var $ul = $li.parent();
+ one.lib.nav.unfocus($ul);
+ $li.addClass('active');
+ // clear respective dashlet
+ var $dashlet = $ul.parent().find('.dashlet');
+ one.lib.dashlet.empty($dashlet);
- // callback based on menu
- var id = $(this).attr('id');
- var menu = one.f.dashlet;
- switch (id) {
- case menu.nodesLearnt.id:
- one.f.switchmanager.nodesLearnt.dashlet($dashlet);
- break;
- case menu.staticRouteConfig.id:
- one.f.switchmanager.staticRouteConfig.dashlet($dashlet);
- break;
- case menu.subnetGatewayConfig.id:
- one.f.switchmanager.subnetGatewayConfig.dashlet($dashlet);
- break;
- case menu.spanPortConfig.id:
- one.f.switchmanager.spanPortConfig.dashlet($dashlet);
- break;
- };
+ // callback based on menu
+ var id = $(this).attr('id');
+ var menu = one.f.dashlet;
+ switch (id) {
+ case menu.nodesLearnt.id:
+ one.f.switchmanager.nodesLearnt.dashlet($dashlet);
+ break;
+ case menu.staticRouteConfig.id:
+ one.f.switchmanager.staticRouteConfig.dashlet($dashlet);
+ break;
+ case menu.subnetGatewayConfig.id:
+ one.f.switchmanager.subnetGatewayConfig.dashlet($dashlet);
+ break;
+ case menu.spanPortConfig.id:
+ one.f.switchmanager.spanPortConfig.dashlet($dashlet);
+ break;
+ case menu.connection.id:
+ one.f.connection.dashlet($dashlet);
+ break;
+ };
});
// activate first tab on each dashlet
$('.dash .nav').each(function(index, value) {
- $($(value).find('li')[0]).find('a').click();
+ $($(value).find('li')[0]).find('a').click();
});