}
override readFlow(FlowKey key) {
- val flowCfg = manager.getStaticFlow(key.id,key.node.toADNode());
+ val flowCfg = manager.getStaticFlow(String.valueOf(key.id), key.node.toADNode());
return flowCfg.toConfigurationFlow;
}
}
idleTimeout = source.idleTimeout
match = source.match
node = source.node
- key = new FlowKey(sourceCfg.name,node);
+ key = new FlowKey(Long.parseLong(sourceCfg.name),node);
return it.build();
}
static def toFlowConfig(Flow sourceCfg) {
val flow = toFlow(sourceCfg);
val it = new FlowConfig;
- name = sourceCfg.key.id
+ name = String.valueOf(sourceCfg.id);
node = sourceCfg.node.toADNode();
return it
static def toFlowConfig(InstanceIdentifier<?> identifier) {
val it = new FlowConfig()
val FlowKey key = ((identifier.path.get(2) as IdentifiableItem<Flow,FlowKey>).key)
- name = key.id;
+ name = String.valueOf(key.id);
node = key.node.toADNode();
return it;
Flow createSampleFlow(String name, NodeRef node) {
FlowBuilder ret = new FlowBuilder();
- FlowKey key = new FlowKey(name, node);
+ FlowKey key = new FlowKey(Long.parseLong(name), node);
ret.setKey(key);
return ret.build();
}
revision "2013-09-25" {
description "Initial revision of Port Inventory model";
}
-
+
+ typedef port-reason {
+ type enumeration {
+ enum add;
+ enum delete;
+ enum update;
+ }
+ }
typedef port-config {
type bits {
enum live;
}
}
-
typedef port-features {
type bits {
}
}
+ grouping flow-port-status {
+ leaf reason {
+ type port-reason;
+ }
+
+ uses flow-capable-port;
+ }
+
grouping flow-capable-port {
uses common-port;
}
}
- grouping ofp-port-mod {
+ grouping port-mod {
container port {
list port {
key "port-mod-order";
key "node id";
leaf id {
- type string;
+ type uint32;
}
uses flow:flow-entry;
}
key "id node";
leaf id {
- type string;
+ type uint32;
}
uses group-entry;
key "id node";
leaf id {
- type string;
+ type uint32;
}
uses meter-entry;
leaf node {
type inv:node-ref;
}
- uses port:ofp-port-mod;
+ uses port:port-mod;
}
container ports {
key "id node";
leaf id {
- type string;
+ type uint32;
}
uses port-entry;
key "id node";
leaf id {
- type string;
+ type uint32;
}
uses table-entry;
enum flow-mod-failed;
enum group-mod-failed;
enum port-mod-failed;
- enum table-mod-failed;
- enum meter-mod-failed;
+ enum table-mod-failed;
enum queue-op-failed;
enum switch-config-failed;
enum role-request-failed;
+ enum meter-mod-failed;
enum table-features-failed;
- enum experimenter;
+ enum experimenter {
+ value "65535";
+ }
}
}
notification node-error-notification {
uses error:error-message;
+ uses tr:transaction-aware;
}
notification node-experimenter-error-notification {
uses error:experimenter-error-message;
+ uses tr:transaction-aware;
}
}
\ No newline at end of file
grouping node-port {
uses "inv:node-context-ref";
- uses port-type:ofp-port-mod;
+ uses port-type:flow-port-status;
}
/** Base configuration structure **/
uses "inv:node-context-ref";
container original-port {
- uses port-type:ofp-port-mod;
+ uses port-type:port-mod;
}
container updated-port {
- uses port-type:ofp-port-mod;
+ uses port-type:port-mod;
}
}
private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
- private static final String FLOW_ID = "foo";
+ private static final long FLOW_ID = 1234;
private static final String NODE_ID = "node:1";
private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
base "config:service-type";
config:java-class "org.opendaylight.controller.sal.binding.api.BindingAwareBroker";
}
+
+ identity binding-data-broker {
+ base "config:service-type";
+ config:java-class "org.opendaylight.controller.sal.binding.api.data.DataProviderService";
+ }
+
+ identity binding-rpc-registry {
+ base "config:service-type";
+ config:java-class "org.opendaylight.controller.sal.binding.api.RpcProviderRegistry";
+ }
+
+ identity binding-notification-service {
+ base "config:service-type";
+ config:java-class "org.opendaylight.controller.sal.binding.api.NotificationProviderService";
+ }
+
}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.sal.connector.netconf.test;
-
-import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.*;
-import io.netty.channel.ChannelFuture;
-import io.netty.util.HashedWheelTimer;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.net.ssl.SSLContext;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
-import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
-import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
-import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClient;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
-import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
-import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager;
-import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
-import org.opendaylight.controller.sal.dom.broker.DataBrokerImpl;
-import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
-public class MountTest extends AbstractConfigTest {
-
- private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
- private static final InetSocketAddress tlsAddress = new InetSocketAddress("127.0.0.1", 12024);
- private static final URI NETCONF_MONITORING_NS = URI.create("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring");
-
- private static final QName NETCONF_MONITORING = new QName(NETCONF_MONITORING_NS, new Date(2010,10,04), "ietf-netconf-monitoring");
- private static final QName NETCONF_MONITORING_STATE = new QName(NETCONF_MONITORING,"netconf-state");
-
-
- private NetconfMessage getConfig, getConfigCandidate, editConfig, closeSession;
- private DefaultCommitNotificationProducer commitNot;
- private NetconfServerDispatcher dispatch;
- private DataProviderService dataBroker;
- private MountPointManagerImpl mountManager;
- private NetconfDeviceManager netconfManager;
-
- private static QName CONFIG_MODULES = new QName(
- URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
- private static QName CONFIG_SERVICES = new QName(
- URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
-
- private NetconfClient createSession(final InetSocketAddress address, NetconfClientDispatcher dispatcher) throws InterruptedException {
- final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000, dispatcher);
- return netconfClient;
- }
-
- @Before
- public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
- new ModuleFactory[0])));
-
- loadMessages();
-
- NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
- factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
-
- commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
-
- dispatch = createDispatcher(Optional.<SSLContext> absent(), factoriesListener);
- ChannelFuture s = dispatch.createServer(tcpAddress);
- s.await();
-
- dataBroker = new DataBrokerImpl();
- mountManager = new MountPointManagerImpl();
- mountManager.setDataBroker(dataBroker);
- netconfManager = new NetconfDeviceManager();
-
- netconfManager.setMountService(mountManager);
- netconfManager.setDataService(dataBroker);
- netconfManager.start();
-
- try (NetconfClient netconfClient = createSession(tcpAddress, netconfManager.getDispatcher())) {
- // send edit_config.xml
- final Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument();
- assertNotNull(rpcReply);
- }
- }
-
-
- protected List<ModuleFactory> getModuleFactories() {
- return getModuleFactoriesS();
- }
-
- static List<ModuleFactory> getModuleFactoriesS() {
- return Lists.newArrayList(new TestImplModuleFactory(), new DepTestImplModuleFactory(),
- new NetconfTestImplModuleFactory());
- }
-
- private void loadMessages() throws IOException, SAXException, ParserConfigurationException {
- this.editConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/edit_config.xml");
- this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
- this.getConfigCandidate = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig_candidate.xml");
- this.closeSession = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/closeSession.xml");
- }
-
- private NetconfServerDispatcher createDispatcher(Optional<SSLContext> sslC,
- NetconfOperationServiceFactoryListenerImpl factoriesListener) {
- SessionIdProvider idProvider = new SessionIdProvider();
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
-
- NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
- factoriesListener, commitNot, idProvider);
-
- return new NetconfServerDispatcher(sslC, serverNegotiatorFactory, listenerFactory);
- }
-
- private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
- final Collection<InputStream> yangDependencies = getBasicYangs();
- return new HardcodedYangStoreService(yangDependencies);
- }
-
- private Collection<InputStream> getBasicYangs() throws IOException {
- List<String> paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang",
- "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang",
- "/META-INF/yang/ietf-inet-types.yang");
- final Collection<InputStream> yangDependencies = new ArrayList<>();
- for (String path : paths) {
- final InputStream is = Preconditions
- .checkNotNull(getClass().getResourceAsStream(path), path + " not found");
- yangDependencies.add(is);
- }
- return yangDependencies;
- }
-
- @Test
- public void test() {
- // MountProvisionInstance mount =
- // Mockito.mock(MountProvisionInstance.class);
- InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH)
- .node(InventoryUtils.INVENTORY_NODE).toInstance();
- netconfManager.netconfNodeAdded(path, tcpAddress);
- InstanceIdentifier mountPointPath = path;
- MountProvisionInstance mountPoint = mountManager.getMountPoint(mountPointPath);
-
- CompositeNode data = mountPoint.readOperationalData(InstanceIdentifier.builder().node(CONFIG_MODULES)
- .toInstance());
- assertNotNull(data);
- assertEquals(CONFIG_MODULES, data.getNodeType());
-
- CompositeNode data2 = mountPoint.readOperationalData(InstanceIdentifier.builder().toInstance());
- assertNotNull(data2);
-
- InstanceIdentifier fullPath = InstanceIdentifier.builder(mountPointPath).node(CONFIG_MODULES).toInstance();
-
- CompositeNode data3 = dataBroker.readOperationalData(fullPath);
- assertNotNull(data3);
- assertEquals(CONFIG_MODULES, data.getNodeType());
- }
-
-}
class JsonReader {
- public CompositeNodeWrapper read(InputStream entityStream) throws UnsupportedJsonFormatException {
+ public CompositeNodeWrapper read(InputStream entityStream) throws UnsupportedFormatException {
JsonParser parser = new JsonParser();
JsonElement rootElement = parser.parse(new InputStreamReader(entityStream));
if (!rootElement.isJsonObject()) {
- throw new UnsupportedJsonFormatException("Root element of Json has to be Object");
+ throw new UnsupportedFormatException("Root element of Json has to be Object");
}
Set<Entry<String, JsonElement>> entrySetsOfRootJsonObject = rootElement.getAsJsonObject().entrySet();
if (entrySetsOfRootJsonObject.size() != 1) {
- throw new UnsupportedJsonFormatException("Json Object should contain one element");
+ throw new UnsupportedFormatException("Json Object should contain one element");
} else {
Entry<String, JsonElement> childEntry = Lists.newArrayList(entrySetsOfRootJsonObject).get(0);
String firstElementName = childEntry.getKey();
if (firstElementInArray.isJsonObject()) {
return createStructureWithRoot(firstElementName, firstElementInArray.getAsJsonObject());
}
- throw new UnsupportedJsonFormatException("Array as the first element in Json Object can have only Object element");
+ throw new UnsupportedFormatException("Array as the first element in Json Object can have only Object element");
}
}
- throw new UnsupportedJsonFormatException("First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
+ throw new UnsupportedFormatException("First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
}
}
JsonReader jsonReader = new JsonReader();
try {
return jsonReader.read(entityStream);
- } catch (UnsupportedJsonFormatException e) {
+ } catch (UnsupportedFormatException e) {
throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
.entity(e.getMessage()).build());
}
singletons.add(restconfImpl);
singletons.add(XmlToCompositeNodeProvider.INSTANCE);
singletons.add(StructuredDataToXmlProvider.INSTANCE);
+ singletons.add(JsonToCompositeNodeProvider.INSTANCE);
+ singletons.add(StructuredDataToJsonProvider.INSTANCE);
return singletons;
}
package org.opendaylight.controller.sal.rest.impl;
-import org.opendaylight.controller.sal.core.api.AbstractProvider;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.core.api.Broker;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.data.DataProviderService;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
-public class RestconfProvider extends AbstractProvider {
+public class RestconfProvider implements BundleActivator, Provider, ServiceTrackerCustomizer<Broker, Broker> {
+ public final static String NOT_INITALIZED_MSG = "Restcof is not initialized yet. Please try again later";
+
private ListenerRegistration<SchemaServiceListener> listenerRegistration;
+ private ServiceTracker<Broker, Broker> brokerServiceTrancker;
+ private BundleContext bundleContext;
+ private ProviderSession session;
@Override
public void onSessionInitiated(ProviderSession session) {
}
@Override
- protected void stopImpl(BundleContext context) {
- super.stopImpl(context);
+ public void start(BundleContext context) throws Exception {
+ bundleContext = context;
+ brokerServiceTrancker = new ServiceTracker<>(context, Broker.class, this);
+ brokerServiceTrancker.open();
+ }
+
+ @Override
+ public void stop(BundleContext context) {
if (listenerRegistration != null) {
try {
listenerRegistration.close();
e.printStackTrace();
}
}
+ session.close();
+ brokerServiceTrancker.close();
+ }
+
+ @Override
+ public Collection<ProviderFunctionality> getProviderFunctionality() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Broker addingService(ServiceReference<Broker> reference) {
+ Broker broker = bundleContext.getService(reference);
+ broker.registerProvider(this, bundleContext);
+ return broker;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<Broker> reference, Broker service) {
+ // NOOP
+ }
+
+ @Override
+ public void removedService(ServiceReference<Broker> reference, Broker service) {
+ bundleContext.ungetService(reference);
+ BrokerFacade.getInstance().setContext(null);
+ BrokerFacade.getInstance().setDataService(null);
+ ControllerContext.getInstance().setSchemas(null);
}
}
import com.google.gson.stream.JsonWriter;
@Provider
-@Produces({ API + RestconfService.JSON })
+@Produces({API+RestconfService.JSON})
public enum StructuredDataToJsonProvider implements MessageBodyWriter<StructuredData> {
INSTANCE;
--- /dev/null
+package org.opendaylight.controller.sal.rest.impl;
+
+public class UnsupportedFormatException extends Exception {
+
+ private static final long serialVersionUID = -1741388894406313402L;
+
+ public UnsupportedFormatException() {
+ super();
+ }
+
+ public UnsupportedFormatException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnsupportedFormatException(String message) {
+ super(message);
+ }
+
+ public UnsupportedFormatException(Throwable cause) {
+ super(cause);
+ }
+
+}
+++ /dev/null
-package org.opendaylight.controller.sal.rest.impl;
-
-public class UnsupportedJsonFormatException extends Exception {
-
- private static final long serialVersionUID = -1741388894406313402L;
-
- public UnsupportedJsonFormatException() {
- super();
- }
-
- public UnsupportedJsonFormatException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public UnsupportedJsonFormatException(String message) {
- super(message);
- }
-
- public UnsupportedJsonFormatException(Throwable cause) {
- super(cause);
- }
-
-}
--- /dev/null
+package org.opendaylight.controller.sal.rest.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Stack;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+
+public class XmlReader {
+
+ private final static XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ private XMLEventReader eventReader;
+
+ public CompositeNodeWrapper read(InputStream entityStream) throws XMLStreamException, UnsupportedFormatException {
+ eventReader = xmlInputFactory.createXMLEventReader(entityStream);
+
+ if (eventReader.hasNext()) {
+ XMLEvent element = eventReader.peek();
+ if (element.isStartDocument()) {
+ eventReader.nextEvent();
+ }
+ }
+
+ if (eventReader.hasNext() && !isCompositeNodeEvent(eventReader.peek())) {
+ throw new UnsupportedFormatException("Root element of XML has to be composite element.");
+ }
+
+ final Stack<NodeWrapper<?>> processingQueue = new Stack<>();
+ CompositeNodeWrapper root = null;
+ NodeWrapper<?> element = null;
+ while (eventReader.hasNext()) {
+ final XMLEvent event = eventReader.nextEvent();
+
+ if (event.isStartElement()) {
+ final StartElement startElement = event.asStartElement();
+ CompositeNodeWrapper compParentNode = null;
+ if (!processingQueue.isEmpty() && processingQueue.peek() instanceof CompositeNodeWrapper) {
+ compParentNode = (CompositeNodeWrapper) processingQueue.peek();
+ }
+ NodeWrapper<?> newNode = null;
+ if (isCompositeNodeEvent(event)) {
+ if (root == null) {
+ root = resolveCompositeNodeFromStartElement(startElement);
+ newNode = root;
+ } else {
+ newNode = resolveCompositeNodeFromStartElement(startElement);
+ }
+ } else if (isSimpleNodeEvent(event)) {
+ if (root == null) {
+ throw new UnsupportedFormatException("Root element of XML has to be composite element.");
+ }
+ newNode = resolveSimpleNodeFromStartElement(startElement);
+ }
+
+ if (newNode != null) {
+ processingQueue.push(newNode);
+ if (compParentNode != null) {
+ compParentNode.addValue(newNode);
+ }
+ }
+ } else if (event.isEndElement()) {
+ element = processingQueue.pop();
+ }
+ }
+
+ if (!root.getLocalName().equals(element.getLocalName())) {
+ throw new UnsupportedFormatException("XML should contain only one root element");
+ }
+
+ return root;
+ }
+
+ private boolean isSimpleNodeEvent(final XMLEvent event) throws XMLStreamException {
+ checkArgument(event != null, "XML Event cannot be NULL!");
+ if (event.isStartElement()) {
+ if (eventReader.hasNext()) {
+ final XMLEvent innerEvent;
+ innerEvent = eventReader.peek();
+ if (innerEvent.isCharacters()) {
+ final Characters chars = innerEvent.asCharacters();
+ if (!chars.isWhiteSpace()) {
+ return true;
+ }
+ } else if (innerEvent.isEndElement()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isCompositeNodeEvent(final XMLEvent event) throws XMLStreamException {
+ checkArgument(event != null, "XML Event cannot be NULL!");
+ if (event.isStartElement()) {
+ if (eventReader.hasNext()) {
+ XMLEvent innerEvent;
+ innerEvent = eventReader.peek();
+ if (innerEvent.isCharacters()) {
+ Characters chars = innerEvent.asCharacters();
+ if (chars.isWhiteSpace()) {
+ eventReader.nextEvent();
+ innerEvent = eventReader.peek();
+ }
+ }
+ if (innerEvent.isStartElement()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private SimpleNodeWrapper resolveSimpleNodeFromStartElement(final StartElement startElement) throws XMLStreamException {
+ checkArgument(startElement != null, "Start Element cannot be NULL!");
+ String data = null;
+
+ if (eventReader.hasNext()) {
+ final XMLEvent innerEvent = eventReader.peek();
+ if (innerEvent.isCharacters()) {
+ final Characters chars = innerEvent.asCharacters();
+ if (!chars.isWhiteSpace()) {
+ data = innerEvent.asCharacters().getData();
+ }
+ } else if (innerEvent.isEndElement()) {
+ data = "";
+ }
+ }
+
+ return new SimpleNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement), data);
+ }
+
+ private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
+ checkArgument(startElement != null, "Start Element cannot be NULL!");
+ return new CompositeNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
+ }
+
+ private String getLocalNameFrom(StartElement startElement) {
+ return startElement.getName().getLocalPart();
+ }
+
+ private URI getNamespaceFrom(StartElement startElement) {
+ String namespaceURI = startElement.getName().getNamespaceURI();
+ return namespaceURI.isEmpty() ? null : URI.create(namespaceURI);
+ }
+
+}
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
@Provider
@Consumes({API+RestconfService.XML})
public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
INSTANCE;
- private final static Logger logger = LoggerFactory.getLogger(XmlToCompositeNodeProvider.class);
-
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
public CompositeNode readFrom(Class<CompositeNode> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
+ XmlReader xmlReader = new XmlReader();
try {
- Node<?> node = XmlTreeBuilder.buildDataTree(entityStream);
- if (node instanceof SimpleNode) {
- logger.info("Node is SimpleNode");
- throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
- .entity("XML should start with XML element that contains 1..N XML child elements.").build());
- }
- return (CompositeNode) node;
- } catch (XMLStreamException e) {
- logger.info("Error during translation of InputStream to Node\n" + e.getMessage());
+ return xmlReader.read(entityStream);
+ } catch (XMLStreamException | UnsupportedFormatException e) {
throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
.entity(e.getMessage()).build());
}
package org.opendaylight.controller.sal.restconf.impl
+import javax.ws.rs.WebApplicationException
+import javax.ws.rs.core.Response
import org.opendaylight.controller.md.sal.common.api.data.DataReader
import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession
import org.opendaylight.controller.sal.core.api.data.DataBrokerService
+import org.opendaylight.controller.sal.rest.impl.RestconfProvider
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
-import static org.opendaylight.controller.sal.restconf.impl.BrokerFacade.*
class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
throw new IllegalStateException("Already instantiated");
}
}
-
+
def static BrokerFacade getInstance() {
return INSTANCE
}
+ private def void checkPreconditions() {
+ if (context == null || dataService == null) {
+ throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
+ .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+ }
+ }
+
override readConfigurationData(InstanceIdentifier path) {
+ checkPreconditions
return dataService.readConfigurationData(path);
}
override readOperationalData(InstanceIdentifier path) {
+ checkPreconditions
return dataService.readOperationalData(path);
}
def RpcResult<CompositeNode> invokeRpc(QName type, CompositeNode payload) {
+ checkPreconditions
val future = context.rpc(type, payload);
return future.get;
}
def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
+ checkPreconditions
val transaction = dataService.beginTransaction;
transaction.putConfigurationData(path, payload);
return transaction.commit()
}
def commitOperationalDataPut(InstanceIdentifier path, CompositeNode payload) {
+ checkPreconditions
val transaction = dataService.beginTransaction;
transaction.putOperationalData(path, payload);
return transaction.commit()
import java.util.HashMap
import java.util.List
import java.util.Map
+import java.util.concurrent.ConcurrentHashMap
+import javax.ws.rs.WebApplicationException
+import javax.ws.rs.core.Response
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.controller.sal.rest.impl.RestconfProvider
import org.opendaylight.yangtools.yang.common.QName
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
import org.opendaylight.yangtools.yang.model.api.SchemaContext
import static com.google.common.base.Preconditions.*
-import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition
-import java.util.concurrent.ConcurrentHashMap
class ControllerContext implements SchemaServiceListener {
static def getInstance() {
return INSTANCE
}
+
+ private def void checkPreconditions() {
+ if (schemas == null) {
+ throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
+ .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+ }
+ }
public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) {
val ret = InstanceIdentifier.builder();
}
private def findModule(String restconfInstance) {
+ checkPreconditions
checkNotNull(restconfInstance);
val pathArgs = restconfInstance.split("/");
if (pathArgs.empty) {
}
def String toFullRestconfIdentifier(InstanceIdentifier path) {
+ checkPreconditions
val elements = path.path;
val ret = new StringBuilder();
val startQName = elements.get(0).nodeType;
}
def CharSequence toRestconfIdentifier(QName qname) {
+ checkPreconditions
var module = uriToModuleName.get(qname.namespace)
if (module == null) {
val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
val List<NodeWrapper<?>> children = (nodeBuilder as CompositeNodeWrapper).getValues
for (child : children) {
addNamespaceToNodeFromSchemaRecursively(child,
- (schema as DataNodeContainer).childNodes.findFirst[n|n.QName.localName === child.localName])
+ (schema as DataNodeContainer).childNodes.findFirst[n|n.QName.localName.equals(child.localName)])
}
}
}
import java.util.Collection;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
restconfImpl.setControllerContext(controllerContext);
}
-// @Before
+ @Before
public void logs() {
List<LogRecord> loggedRecords = getLoggedRecords();
for (LogRecord l : loggedRecords) {
public void testXmlToCompositeNodeProvider() throws ParserConfigurationException, SAXException, IOException {
URI uri = null;
try {
- uri = new URI("/operations/" + URLEncoder.encode("ietf-interfaces:interfaces/interface/eth0", Charsets.US_ASCII.name()).toString());
+ uri = new URI("/config/" + URLEncoder.encode("ietf-interfaces:interfaces/interface/eth0", Charsets.US_ASCII.name()).toString());
} catch (UnsupportedEncodingException | URISyntaxException e) {
e.printStackTrace();
}
InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
final CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
- when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(new RpcResult<CompositeNode>() {
-
+ when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(new Future<RpcResult<TransactionStatus>>() {
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return false;
+ }
@Override
- public boolean isSuccessful() {
- return true;
+ public boolean isCancelled() {
+ return false;
}
-
@Override
- public CompositeNode getResult() {
- return loadedCompositeNode;
+ public boolean isDone() {
+ return false;
}
-
@Override
- public Collection<RpcError> getErrors() {
+ public RpcResult<TransactionStatus> get() throws InterruptedException, ExecutionException {
+ return null;
+ }
+ @Override
+ public RpcResult<TransactionStatus> get(long timeout, TimeUnit unit) throws InterruptedException,
+ ExecutionException, TimeoutException {
return null;
}
});
Document doc = docBuilder.parse(xmlStream);
Response response = target(uri.toASCIIString()).request(MediaTypes.API+RestconfService.XML).post(Entity.entity(TestUtils.getDocumentInPrintableForm(doc), new MediaType("application","vnd.yang.api+xml")));
- assertEquals(200, response.getStatus());
+ assertEquals(204, response.getStatus());
}
@Test