--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-subsystem</artifactId>
+ <version>0.2.5-SNAPSHOT</version>
+ <relativePath>../../opendaylight/config/</relativePath>
+ </parent>
+ <artifactId>config-netty-features</artifactId>
+
+ <packaging>pom</packaging>
+
+ <properties>
+ <features.file>features.xml</features.file>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-persister-features</artifactId>
+ <version>${config.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+ </scm>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-config-persister-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+ <repository>mvn:org.opendaylight.controller/config-persister-features/${config.version}/xml/features</repository>
+ <feature name='odl-config-netty' version='${project.version}'>
+ <feature version='${project.version}'>odl-config-netty-config-api</feature>
+ <bundle>mvn:org.opendaylight.controller/netty-event-executor-config/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/netty-threadgroup-config/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/netty-timer-config/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/threadpool-config-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/threadpool-config-impl/${project.version}</bundle>
+ <feature version='${project.version}'>odl-config-startup</feature>
+ </feature>
+</features>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-subsystem</artifactId>
+ <version>0.2.5-SNAPSHOT</version>
+ <relativePath>../../opendaylight/config/</relativePath>
+ </parent>
+ <artifactId>config-persister-features</artifactId>
+
+ <packaging>pom</packaging>
+
+ <properties>
+ <features.file>features.xml</features.file>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-features</artifactId>
+ <version>${netconf.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-features</artifactId>
+ <version>${config.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+ </scm>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="odl-config-persister-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+ <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/netconf-features/${netconf.version}/xml/features</repository>
+ <repository>mvn:org.opendaylight.controller/config-features/${config.version}/xml/features</repository>
+ <feature name='odl-config-startup' version='${project.version}'>
+ <feature version='${project.version}'>odl-config-netconf-connector</feature>
+ <feature version='${project.version}'>odl-config-persister</feature>
+ <feature version='${project.version}'>odl-netconf-impl</feature>
+ </feature>
+ <feature name='odl-config-persister' version='${project.version}'>
+ <feature version='${netconf.version}'>odl-netconf-api</feature>
+ <feature version='${project.version}'>odl-config-api</feature>
+ <feature version='${yangtools.version}'>yangtools-binding-generator</feature>
+ <bundle>mvn:org.opendaylight.controller/config-persister-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/config-persister-file-xml-adapter/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/config-persister-directory-xml-adapter/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/config-persister-impl/${project.version}</bundle>
+
+ <bundle>mvn:org.opendaylight.controller/netconf-util/${netconf.version}</bundle>
+ <bundle>mvn:org.opendaylight.controller/netconf-mapping-api/${netconf.version}</bundle>
+
+ <bundle>mvn:com.google.guava/guava/${guava.version}</bundle>
+ <bundle>mvn:commons-io/commons-io/${commons.io.version}</bundle>
+ <bundle>mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
+ <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.core/${eclipse.persistence.version}</bundle>
+ <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/${eclipse.persistence.version}</bundle>
+ </feature>
+</features>
\ No newline at end of file
<features.file>features.xml</features.file>
</properties>
- <dependencies></dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
<build>
<resources>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
<repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/netconf-features/${netconf.version}/xml/features</repository>
-
- <feature name='odl-config-startup' version='${project.version}'>
- <feature version='${project.version}'>odl-config-netconf-connector</feature>
- <feature version='${project.version}'>odl-config-persister</feature>
- <feature version='${project.version}'>odl-netconf-impl</feature>
- </feature>
<feature name='odl-config-core' version='${project.version}'>
<feature version='${yangtools.version}'>yangtools-concepts</feature>
<feature version='${project.version}'>odl-config-core</feature>
<bundle>mvn:org.opendaylight.controller/config-manager/${project.version}</bundle>
</feature>
- <feature name='odl-config-persister' version='${project.version}'>
- <feature version='${netconf.version}'>odl-netconf-api</feature>
- <feature version='${project.version}'>odl-config-api</feature>
- <feature version='${yangtools.version}'>yangtools-binding-generator</feature>
- <bundle>mvn:org.opendaylight.controller/config-persister-api/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/config-persister-file-xml-adapter/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/config-persister-directory-xml-adapter/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/config-persister-impl/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netconf-util/${netconf.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netconf-mapping-api/${netconf.version}</bundle>
-
- <bundle>mvn:com.google.guava/guava/${guava.version}</bundle>
- <bundle>mvn:commons-io/commons-io/${commons.io.version}</bundle>
- <bundle>mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
- <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.core/${eclipse.persistence.version}</bundle>
- <bundle>mvn:org.eclipse.persistence/org.eclipse.persistence.moxy/${eclipse.persistence.version}</bundle>
- </feature>
<feature name='odl-config-api' version='${project.version}'>
<bundle>mvn:org.opendaylight.controller/config-api/${project.version}</bundle>
<feature version='${project.version}'>odl-config-api</feature>
</feature>
- <feature name='odl-config-netty' version='${project.version}'>
- <feature version='${project.version}'>odl-config-netty-config-api</feature>
- <bundle>mvn:org.opendaylight.controller/netty-event-executor-config/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netty-threadgroup-config/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netty-timer-config/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/threadpool-config-api/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/threadpool-config-impl/${project.version}</bundle>
- <feature version='${project.version}'>odl-config-startup</feature>
- </feature>
<feature name='odl-config-dispatcher' version='${project.version}'>
<bundle>mvn:org.opendaylight.controller/netconf-config-dispatcher/${project.version}</bundle>
</feature>
<features.file>features.xml</features.file>
</properties>
- <dependencies></dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-features</artifactId>
+ <version>${config.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>features-odl-protocol-framework</artifactId>
+ <version>${protocol-framework.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
<build>
<resources>
</prerequisites>
<modules>
<module>config</module>
+ <module>config-persister</module>
+ <module>config-netty</module>
<module>mdsal</module>
<module>netconf</module>
<module>protocol-framework</module>
<features.file>features.xml</features.file>
</properties>
- <dependencies></dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-features</artifactId>
+ <version>${config.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
<build>
<resources>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>features-odl-protocol-framework</artifactId>
- <version>${protocol-framework.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-features</artifactId>
- <version>${netconf.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-features</artifactId>
+ <artifactId>config-netty-features</artifactId>
<version>${config.version}</version>
<classifier>features</classifier>
<type>xml</type>
}
continue;
}
+
sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
if (sstr.matches()) {
if (!NetUtils.isIPAddressValid(sstr.group(1))) {
}
continue;
}
- }
+
+ sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.FLOOD_ALL.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
+ if (sstr.matches()) {
+ continue;
+ }
+
+ // If execution reached here, it means there is an Action
+ // which is not recognized by the controller. Return error
+
+ return new Status(StatusCode.BADREQUEST, String.format("%s is an UnSupported Action", actiongrp));
+ }
} catch (NumberFormatException e) {
return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
}
actions.add(ActionType.SET_NW_SRC.toString() + "=1.1.1.1");
actions.add(ActionType.SET_NW_DST.toString() + "=2.2.2.2");
actions.add(ActionType.CONTROLLER.toString());
- actions.add(ActionType.SET_NW_TOS.toString() + "1");
- actions.add(ActionType.SET_TP_SRC.toString() + "60");
- actions.add(ActionType.SET_TP_DST.toString() + "8080");
+ actions.add(ActionType.SET_NW_TOS.toString() + "=1");
+ actions.add(ActionType.SET_TP_SRC.toString() + "=60");
+ actions.add(ActionType.SET_TP_DST.toString() + "=8080");
actions.add(ActionType.SET_NEXT_HOP.toString() + "=1.1.1.1");
return actions;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-public interface BindingTransactionChain extends TransactionChain<InstanceIdentifier<?>, DataObject> {
+public interface BindingTransactionChain extends TransactionFactory, TransactionChain<InstanceIdentifier<?>, DataObject> {
@Override
ReadOnlyTransaction newReadOnlyTransaction();
* <p>
* For more information on usage, please see the documentation in {@link AsyncDataBroker}.
*/
-public interface DataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService, TransactionChainFactory<InstanceIdentifier<?>, DataObject> {
+public interface DataBroker extends TransactionFactory, AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService, TransactionChainFactory<InstanceIdentifier<?>, DataObject> {
+
@Override
ReadOnlyTransaction newReadOnlyTransaction();
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.binding.api;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+
+public interface MountPoint extends Identifiable<InstanceIdentifier<?>>{
+
+ <T extends BindingAwareService> Optional<T> getService(Class<T> service);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.binding.api;
+
+import java.util.EventListener;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+
+public interface MountPointService {
+
+ Optional<MountPoint> getMountPoint(InstanceIdentifier<?> mountPoint);
+
+ <T extends MountPointListener> ListenerRegistration<T> registerListener(InstanceIdentifier<?> path, T listener);
+
+
+ public interface MountPointListener extends EventListener {
+
+ void onMountPointCreated(InstanceIdentifier<?> path);
+
+ void onMountPointRemoved(InstanceIdentifier<?> path);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.binding.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataTransactionFactory;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface TransactionFactory extends AsyncDataTransactionFactory<InstanceIdentifier<?>, DataObject>{
+
+ @Override
+ ReadOnlyTransaction newReadOnlyTransaction();
+
+ @Override
+ ReadWriteTransaction newReadWriteTransaction();
+
+ @Override
+ WriteTransaction newWriteOnlyTransaction();
+
+}
*/
public interface DOMDataBroker extends
AsyncDataBroker<InstanceIdentifier, NormalizedNode<?, ?>, DOMDataChangeListener>,
- TransactionChainFactory<InstanceIdentifier, NormalizedNode<?, ?>>, BrokerService {
+ TransactionChainFactory<InstanceIdentifier, NormalizedNode<?, ?>>, BrokerService, DOMService {
/**
* {@inheritDoc}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.dom.api;
+
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public interface DOMMountPoint extends Identifiable<InstanceIdentifier> {
+
+ <T extends DOMService> Optional<T> getService(Class<T> cls);
+
+ SchemaContext getSchemaContext();
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.dom.api;
+
+import org.opendaylight.controller.sal.core.api.BrokerService;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.base.Optional;
+
+
+public interface DOMMountPointService extends BrokerService {
+
+ Optional<DOMMountPoint> getMountPoint(InstanceIdentifier path);
+
+ DOMMountPointBuilder createMountPoint(InstanceIdentifier path);
+
+
+ public interface DOMMountPointBuilder {
+
+ <T extends DOMService> DOMMountPointBuilder addService(Class<T> type,T impl);
+
+ DOMMountPointBuilder addInitialSchemaContext(SchemaContext ctx);
+
+ ObjectRegistration<DOMMountPoint> register();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.dom.api;
+
+public interface DOMService {
+
+}
package org.opendaylight.controller.sal.core.api;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-public interface RpcProvisionRegistry extends RpcImplementation, BrokerService, RouteChangePublisher<RpcRoutingContext, InstanceIdentifier> {
+public interface RpcProvisionRegistry extends RpcImplementation, BrokerService, RouteChangePublisher<RpcRoutingContext, InstanceIdentifier>, DOMService {
/**
* Registers an implementation of the rpc.
* Interface representing a single mount instance and represents a way for
* clients to access underlying data, RPCs and notifications.
*/
+@Deprecated
public interface MountInstance extends //
NotificationService, //
DataBrokerService {
import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+@Deprecated
public interface MountProvisionInstance extends //
MountInstance,//
NotificationPublishService, //
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+/**
+ * @deprecated Use org.opendaylight.controller.md.sal.dom.api.DOMMountPointService instead
+ */
+@Deprecated
public interface MountProvisionService extends MountService {
@Override
/**
* Client-level interface for interacting with mount points. It provides access
* to {@link MountInstance} instances based on their path.
+ *
+ * @deprecated Use org.opendaylight.controller.md.sal.dom.api.DOMMountPointService instead
*/
+@Deprecated
public interface MountService extends BrokerService {
/**
* Obtain access to a mount instance registered at the specified path.
*/
package org.opendaylight.controller.sal.core.api.notify;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
/**
* {@link NotificationListener#onNotification(CompositeNode)}
* </ol>
*/
-public interface NotificationPublishService extends NotificationService {
+public interface NotificationPublishService extends NotificationService, DOMService {
/**
* Publishes a notification.
*
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.dom.broker.impl.mount;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
+import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoint;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
+
+public class DOMMountPointServiceImpl implements DOMMountPointService {
+
+ private final Map<InstanceIdentifier, SimpleDOMMountPoint> mountPoints = new HashMap<>();
+
+ @Override
+ public Optional<DOMMountPoint> getMountPoint(final InstanceIdentifier path) {
+ return Optional.<DOMMountPoint>fromNullable(mountPoints.get(path));
+ }
+
+ @Override
+ public DOMMountPointBuilder createMountPoint(final InstanceIdentifier path) {
+ Preconditions.checkState(!mountPoints.containsKey(path), "Mount point already exists");
+ return new DOMMountPointBuilderImpl(path);
+ }
+
+ public ObjectRegistration<DOMMountPoint> registerMountPoint(final SimpleDOMMountPoint mountPoint) {
+ synchronized (mountPoints) {
+ Preconditions.checkState(!mountPoints.containsKey(mountPoint.getIdentifier()), "Mount point already exists");
+ mountPoints.put(mountPoint.getIdentifier(), mountPoint);
+ }
+ return null;
+ }
+
+ public class DOMMountPointBuilderImpl implements DOMMountPointBuilder {
+
+ ClassToInstanceMap<DOMService> services = MutableClassToInstanceMap.create();
+ private SimpleDOMMountPoint mountPoint;
+ private final InstanceIdentifier path;
+ private SchemaContext schemaContext;
+
+ public DOMMountPointBuilderImpl(final InstanceIdentifier path) {
+ this.path = path;
+ }
+
+ @Override
+ public <T extends DOMService> DOMMountPointBuilder addService(final Class<T> type, final T impl) {
+ services.putInstance(type, impl);
+ return this;
+ }
+
+ @Override
+ public DOMMountPointBuilder addInitialSchemaContext(final SchemaContext ctx) {
+ schemaContext = ctx;
+ return this;
+ }
+
+ @Override
+ public ObjectRegistration<DOMMountPoint> register() {
+ Preconditions.checkState(mountPoint == null, "Mount point is already built.");
+ mountPoint = SimpleDOMMountPoint.create(path, services,schemaContext);
+ return registerMountPoint(mountPoint);
+ }
+ }
+}
import com.google.common.util.concurrent.ListenableFuture;
+@Deprecated
public class MountPointImpl implements MountProvisionInstance, SchemaContextProvider {
private final SchemaAwareRpcBroker rpcs;
import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+@Deprecated
public class MountPointManagerImpl implements MountProvisionService {
private final ListenerRegistry<MountProvisionListener> listeners =
--- /dev/null
+/*
+ * Copyright (c) 2014 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.md.sal.dom.broker.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService.DOMMountPointBuilder;
+import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class MountPointServiceTest {
+
+ private DOMMountPointService mountService;
+ private static final InstanceIdentifier PATH = InstanceIdentifier.of(QName.create("namespace", "12-12-2012", "top"));
+
+ @Before
+ public void setup() {
+ mountService = new DOMMountPointServiceImpl();
+ }
+
+ @Test
+ public void createSimpleMountPoint() {
+ Optional<DOMMountPoint> mountNotPresent = mountService.getMountPoint(PATH);
+ assertFalse(mountNotPresent.isPresent());
+ DOMMountPointBuilder mountBuilder = mountService.createMountPoint(PATH);
+ mountBuilder.register();
+
+ Optional<DOMMountPoint> mountPresent = mountService.getMountPoint(PATH);
+ assertTrue(mountPresent.isPresent());
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.dom.broker.spi.mount;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
+import org.opendaylight.controller.md.sal.dom.api.DOMService;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
+
+public class SimpleDOMMountPoint implements DOMMountPoint {
+
+ private final InstanceIdentifier identifier;
+ private final ClassToInstanceMap<DOMService> services;
+ private final SchemaContext schemaContext;
+
+ public static final SimpleDOMMountPoint create(final InstanceIdentifier identifier, final ClassToInstanceMap<DOMService> services, final SchemaContext ctx) {
+ return new SimpleDOMMountPoint(identifier, services, ctx);
+ }
+ private SimpleDOMMountPoint(final InstanceIdentifier identifier, final ClassToInstanceMap<DOMService> services, final SchemaContext ctx) {
+ this.identifier = identifier;
+ this.services = ImmutableClassToInstanceMap.copyOf(services);
+ this.schemaContext = ctx;
+ }
+
+ @Override
+ public InstanceIdentifier getIdentifier() {
+ return identifier;
+ }
+
+ @Override
+ public SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
+ @Override
+ public <T extends DOMService> Optional<T> getService(final Class<T> cls) {
+ return Optional.fromNullable(services.getInstance(cls));
+ }
+}
package org.opendaylight.controller.sal.connect.netconf.listener;
-import java.util.Arrays;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
import java.util.Collection;
+import java.util.HashSet;
import java.util.Set;
import org.opendaylight.controller.netconf.client.NetconfClientSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-
public final class NetconfSessionCapabilities {
+ private static final class ParameterMatcher {
+ private final Predicate<String> predicate;
+ private final int skipLength;
+
+ ParameterMatcher(final String name) {
+ predicate = new Predicate<String>() {
+ @Override
+ public boolean apply(final String input) {
+ return input.startsWith(name);
+ }
+ };
- private static final Logger logger = LoggerFactory.getLogger(NetconfSessionCapabilities.class);
+ this.skipLength = name.length();
+ }
- private final Set<String> capabilities;
+ private String from(final Iterable<String> params) {
+ final Optional<String> o = Iterables.tryFind(params, predicate);
+ if (!o.isPresent()) {
+ return null;
+ }
+
+ return o.get().substring(skipLength);
+ }
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfSessionCapabilities.class);
+ private static final ParameterMatcher MODULE_PARAM = new ParameterMatcher("module=");
+ private static final ParameterMatcher REVISION_PARAM = new ParameterMatcher("revision=");
+ private static final ParameterMatcher BROKEN_REVISON_PARAM = new ParameterMatcher("amp;revision=");
+ private static final Splitter AMP_SPLITTER = Splitter.on('&');
+ private static final Predicate<String> CONTAINS_REVISION = new Predicate<String>() {
+ @Override
+ public boolean apply(final String input) {
+ return input.contains("revision=");
+ }
+ };
private final Set<QName> moduleBasedCaps;
+ private final Set<String> capabilities;
private NetconfSessionCapabilities(final Set<String> capabilities, final Set<QName> moduleBasedCaps) {
- this.capabilities = capabilities;
- this.moduleBasedCaps = moduleBasedCaps;
+ this.capabilities = Preconditions.checkNotNull(capabilities);
+ this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps);
}
public Set<QName> getModuleBasedCaps() {
}
public static NetconfSessionCapabilities fromStrings(final Collection<String> capabilities) {
- final Set<QName> moduleBasedCaps = Sets.newHashSet();
+ final Set<QName> moduleBasedCaps = new HashSet<>();
for (final String capability : capabilities) {
- if(isModuleBasedCapability(capability)) {
- final String[] parts = capability.split("\\?");
- final String namespace = parts[0];
- final FluentIterable<String> queryParams = FluentIterable.from(Arrays.asList(parts[1].split("&")));
-
- String revision = getStringAndTransform(queryParams, "revision=", "revision=");
-
- final String moduleName = getStringAndTransform(queryParams, "module=", "module=");
+ final int qmark = capability.indexOf('?');
+ if (qmark == -1) {
+ continue;
+ }
- if (revision == null) {
- logger.debug("Netconf device was not reporting revision correctly, trying to get amp;revision=");
- revision = getStringAndTransform(queryParams, "amp;revision=", "amp;revision=");
+ final String namespace = capability.substring(0, qmark);
+ final Iterable<String> queryParams = AMP_SPLITTER.split(capability.substring(qmark + 1));
+ final String moduleName = MODULE_PARAM.from(queryParams);
+ if (moduleName == null) {
+ continue;
+ }
- if (revision == null) {
- logger.warn("Netconf device returned revision incorrectly escaped for {}", capability);
- }
- }
+ String revision = REVISION_PARAM.from(queryParams);
+ if (revision != null) {
moduleBasedCaps.add(QName.create(namespace, revision, moduleName));
+ continue;
}
- }
-
- return new NetconfSessionCapabilities(Sets.newHashSet(capabilities), moduleBasedCaps);
- }
- private static boolean isModuleBasedCapability(final String capability) {
- return capability.contains("?") && capability.contains("module=") && capability.contains("revision=");
- }
+ /*
+ * We have seen devices which mis-escape revision, but the revision may not
+ * even be there. First check if there is a substring that matches revision.
+ */
+ if (!Iterables.any(queryParams, CONTAINS_REVISION)) {
+ continue;
+ }
- private static String getStringAndTransform(final Iterable<String> queryParams, final String match,
- final String substringToRemove) {
- final Optional<String> found = Iterables.tryFind(queryParams, new Predicate<String>() {
- @Override
- public boolean apply(final String input) {
- return input.startsWith(match);
+ LOG.debug("Netconf device was not reporting revision correctly, trying to get amp;revision=");
+ revision = BROKEN_REVISON_PARAM.from(queryParams);
+ if (revision == null) {
+ LOG.warn("Netconf device returned revision incorrectly escaped for {}, ignoring it", capability);
}
- });
- return found.isPresent() ? found.get().replaceAll(substringToRemove, "") : null;
- }
+ // FIXME: do we really want to continue here?
+ moduleBasedCaps.add(QName.create(namespace, revision, moduleName));
+ }
+ return new NetconfSessionCapabilities(ImmutableSet.copyOf(capabilities), ImmutableSet.copyOf(moduleBasedCaps));
+ }
}
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.net.URI;
import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.Node;
return null;
}
- for (final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument component : Lists
- .reverse(identifier.getPath())) {
+ for (final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument component : identifier.getReversePathArguments()) {
if (component instanceof InstanceIdentifier.NodeIdentifierWithPredicates) {
previous = toNode((InstanceIdentifier.NodeIdentifierWithPredicates)component, previous);
} else {
ErrorSeverity severity = toRpcErrorSeverity( ex.getErrorSeverity() );
return severity == ErrorSeverity.ERROR ?
- RpcResultBuilder.newError(
+ RpcResultBuilder.newError(
toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() ) :
- RpcResultBuilder.newWarning(
- toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
- ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() );
+ RpcResultBuilder.newWarning(
+ toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
+ ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() );
}
private static ErrorSeverity toRpcErrorSeverity( final NetconfDocumentedException.ErrorSeverity severity ) {
device.onRemoteSessionUp(sessionCaps, listener);
verify(messageTransformer, timeout(10000).times(2)).toNotification(netconfMessage);
- verify(facade, times(2)).onNotification(compositeNode);
+ verify(facade, timeout(10000).times(2)).onNotification(compositeNode);
device.onNotification(netconfMessage);
- verify(messageTransformer, times(3)).toNotification(netconfMessage);
- verify(facade, times(3)).onNotification(compositeNode);
+ verify(messageTransformer, timeout(10000).times(3)).toNotification(netconfMessage);
+ verify(facade, timeout(10000).times(3)).onNotification(compositeNode);
}
@Test
}
final String identifierDecoded = controllerContext.urlPathArgDecode(identifierEncoded);
- RpcDefinition rpc = controllerContext.getRpcDefinition(identifierDecoded);
+
+ RpcDefinition rpc = null;
+ if (mountPoint == null) {
+ rpc = controllerContext.getRpcDefinition(identifierDecoded);
+ } else {
+ rpc = findRpc(mountPoint.getSchemaContext(), identifierDecoded);
+ }
if (rpc == null) {
throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT);
}
+ private RpcDefinition findRpc(final SchemaContext schemaContext, final String identifierDecoded) {
+ final String[] splittedIdentifier = identifierDecoded.split(":");
+ if (splittedIdentifier.length != 2) {
+ throw new RestconfDocumentedException(identifierDecoded
+ + " couldn't be splitted to 2 parts (module:rpc name)", ErrorType.APPLICATION,
+ ErrorTag.INVALID_VALUE);
+ }
+ for (Module module : schemaContext.getModules()) {
+ if (module.getName().equals(splittedIdentifier[0])) {
+ for (RpcDefinition rpcDefinition : module.getRpcs()) {
+ if (rpcDefinition.getQName().getLocalName().equals(splittedIdentifier[1])) {
+ return rpcDefinition;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload, boolean prettyPrint) {
if (rpcExecutor == null) {
throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT);
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-
import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
assertNotNull(output.getSchema());
}
+ /**
+ *
+ * Tests calling of RestConfImpl method invokeRpc. In the method there is searched rpc in remote schema context.
+ * This rpc is then executed.
+ *
+ * I wasn't able to simulate calling of rpc on remote device therefore this testing method raise method when rpc is
+ * invoked.
+ */
@Test
public void testMountedRpcCallNoPayload_Success() throws Exception {
RpcResult<CompositeNode> rpcResult = RpcResultBuilder.<CompositeNode>success().build();
MountInstance mockMountPoint = mock(MountInstance.class);
when(mockMountPoint.rpc(eq(cancelToastQName), any(CompositeNode.class))).thenReturn(mockListener);
+ when(mockMountPoint.getSchemaContext()).thenReturn(TestUtils.loadSchemaContext("/invoke-rpc"));
+
InstanceIdWithSchemaNode mockedInstanceId = mock(InstanceIdWithSchemaNode.class);
when(mockedInstanceId.getMountPoint()).thenReturn(mockMountPoint);
ControllerContext mockedContext = mock(ControllerContext.class);
- String cancelToastStr = "toaster:cancel-toast";
- when(mockedContext.urlPathArgDecode(cancelToastStr)).thenReturn(cancelToastStr);
- when(mockedContext.getRpcDefinition(cancelToastStr)).thenReturn(mockRpc);
+ String rpcNoop = "invoke-rpc-module:rpc-noop";
+ when(mockedContext.urlPathArgDecode(rpcNoop)).thenReturn(rpcNoop);
+ when(mockedContext.getRpcDefinition(rpcNoop)).thenReturn(mockRpc);
when(
- mockedContext.toMountPointIdentifier("opendaylight-inventory:nodes/node/"
- + "REMOTE_HOST/yang-ext:mount/toaster:cancel-toast")).thenReturn(mockedInstanceId);
+ mockedContext.toMountPointIdentifier(eq("opendaylight-inventory:nodes/node/"
+ + "REMOTE_HOST/yang-ext:mount/invoke-rpc-module:rpc-noop"))).thenReturn(mockedInstanceId);
restconfImpl.setControllerContext(mockedContext);
- StructuredData output = restconfImpl.invokeRpc(
- "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast", "", uriInfo);
- assertEquals(null, output);
+ try {
+ restconfImpl.invokeRpc(
+ "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/invoke-rpc-module:rpc-noop", "",
+ uriInfo);
+ fail("RestconfDocumentedException wasn't raised");
+ } catch (RestconfDocumentedException e) {
+ List<RestconfError> errors = e.getErrors();
+ assertNotNull(errors);
+ assertEquals(1, errors.size());
+ assertEquals(ErrorType.APPLICATION, errors.iterator().next().getErrorType());
+ assertEquals(ErrorTag.OPERATION_FAILED, errors.iterator().next().getErrorTag());
+ }
// additional validation in the fact that the restconfImpl does not
// throw an exception.
}
}
}
-
+
+ rpc rpc-noop {
+ }
+
}
\ No newline at end of file