import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.concurrent.ConcurrentMap;
import org.opendaylight.controller.hosttracker.IfHostListener;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.switchmanager.ISwitchManager;
import org.opendaylight.controller.switchmanager.Subnet;
import org.opendaylight.controller.topologymanager.ITopologyManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ArpHandler implements IHostFinder, IListenDataPacket {
private static final Logger logger = LoggerFactory
private IDataPacketService dataPacketService = null;
private Set<IfHostListener> hostListener = Collections
.synchronizedSet(new HashSet<IfHostListener>());
- private ConcurrentHashMap<InetAddress, Set<HostNodeConnector>> arpRequestors;
- private ConcurrentHashMap<InetAddress, Short> countDownTimers;
+ private ConcurrentMap<InetAddress, Set<HostNodeConnector>> arpRequestors;
+ private ConcurrentMap<InetAddress, Short> countDownTimers;
private Timer periodicTimer;
void setHostListener(IfHostListener s) {
package org.opendaylight.controller.clustering.services_implementation.internal;
import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+import org.opendaylight.controller.sal.core.IContainerAware;
import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
* ComponentActivatorAbstractBase.
*
*/
+ @Override
public void init() {
}
* cleanup done by ComponentActivatorAbstractBase
*
*/
+ @Override
public void destroy() {
}
* instantiated in order to get an fully working implementation
* Object
*/
+ @Override
public Object[] getGlobalImplementations() {
Object[] res = { ClusterManager.class, ClusterGlobalManager.class };
return res;
* instantiated in order to get an fully working implementation
* Object
*/
+ @Override
public Object[] getImplementations() {
Object[] res = { ClusterContainerManager.class };
return res;
* also optional per-container different behavior if needed, usually
* should not be the case though.
*/
+ @Override
public void configureInstance(Component c, Object imp, String containerName) {
if (imp.equals(ClusterContainerManager.class)) {
c.setInterface(new String[] { IClusterContainerServices.class.getName() },
* needed as long as the same routine can configure multiple
* implementations
*/
+ @Override
public void configureGlobalInstance(Component c, Object imp) {
if (imp.equals(ClusterManager.class)) {
// export the service for Apps and Plugins
- c.setInterface(new String[] { IClusterServices.class.getName() }, null);
+ c.setInterface(new String[] { IClusterServices.class.getName(), IContainerAware.class.getName() }, null);
}
if (imp.equals(ClusterGlobalManager.class)) {
package org.opendaylight.controller.clustering.services_implementation.internal;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import org.opendaylight.controller.clustering.services.IGetUpdates;
import org.opendaylight.controller.clustering.services.IListenRoleChange;
import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
+import org.opendaylight.controller.sal.core.IContainerAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ClusterManager implements IClusterServices {
+public class ClusterManager implements IClusterServices, IContainerAware {
protected static final Logger logger = LoggerFactory
.getLogger(ClusterManager.class);
private DefaultCacheManager cm;
try {
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements()) {
- NetworkInterface n = (NetworkInterface) e.nextElement();
+ NetworkInterface n = e.nextElement();
Enumeration<InetAddress> ee = n.getInetAddresses();
while (ee.hasMoreElements()) {
- InetAddress i = (InetAddress) ee.nextElement();
+ InetAddress i = ee.nextElement();
myAddresses.add(i);
}
}
return null;
}
+ @Override
public List<InetAddress> getClusteredControllers() {
EmbeddedCacheManager manager = this.cm;
if (manager == null) {
return null;
}
List<Address> controllers = manager.getMembers();
- if ((controllers == null) || controllers.size() == 0)
+ if ((controllers == null) || controllers.size() == 0) {
return null;
+ }
List<InetAddress> clusteredControllers = new ArrayList<InetAddress>();
for (Address a : controllers) {
InetAddress inetAddress = addressToInetAddress(a);
if (inetAddress != null
- && !inetAddress.getHostAddress().equals(loopbackAddress))
+ && !inetAddress.getHostAddress().equals(loopbackAddress)) {
clusteredControllers.add(inetAddress);
+ }
}
return clusteredControllers;
}
+ @Override
public InetAddress getMyAddress() {
EmbeddedCacheManager manager = this.cm;
if (manager == null) {
}
}
}
+
+ private void removeContainerCaches(String containerName) {
+ logger.info("Destroying caches for container {}", containerName);
+ for (String cacheName : this.getCacheList(containerName)) {
+ this.destroyCache(containerName, cacheName);
+ }
+ }
+
+ @Override
+ public void containerCreate(String arg0) {
+ // no op
+ }
+
+ @Override
+ public void containerDestroy(String container) {
+ removeContainerCaches(container);
+ }
}
<virgo.version>3.6.0.RELEASE</virgo.version>
<geminiweb.version>2.2.0.RELEASE</geminiweb.version>
<checkstyle.version>2.10</checkstyle.version>
+ <testvm.argLine>-Xmx1024m -XX:MaxPermSize=256m</testvm.argLine>
</properties>
<pluginRepositories>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${failsafe.version}</version>
+ <configuration>
+ <argLine>${testvm.argLine}</argLine>
+ </configuration>
<executions>
<execution>
<goals>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
+ <configuration>
+ <argLine>${testvm.argLine}</argLine>
+ </configuration>
</plugin>
</plugins>
<pluginManagement>
# of.messageResponseTimer=2000
# The switch liveness timeout value (default 60500 msec)
# of.switchLivenessTimeout=60500
+# The size of the queue holding pending statistics requests (default 64). For large networks of n switches, it is recommended to set the queue size to n
+# of.statsQueueSize = 64
# The flow statistics polling interval in second (default 10 sec)
# of.flowStatsPollInterval=10
# The port statistics polling interval in second (default 5 sec)
# The description statistics polling interval in second (default 60 sec)
# of.descStatsPollInterval=60
# The table statistics polling interval in second (default 10 sec)
-# of.tableStatsPollInterval=10
+# of.tableStatsPollInterval=10
# The maximum number of asynchronous messages can be sent before sending a Barrier Request (default 100)
# of.barrierMessagePriorCount=100
# The interval which determines how often the discovery packets should be sent (default 300 sec)
# of.discoveryInterval=300
-# The timeout value in waiting for returned discovery packet (default 60 sec)
-# of.discoveryTimeout=60
-# The number of retries after the initial discovery packet is not received within the timeout period (default 2)
-# of.discoveryRetry=2
+# The timeout multiple of discovery interval
+# of.discoveryTimeoutMultiple=2
+# For newly added ports, allow one more retry if the elapsed time exceeds this threshold (default 30 sec)
+# of.discoveryThreshold=30
+# The maximum number of ports handled in one discovery batch (default 1024)
+# of.discoveryBatchMaxPorts=1024
# TLS configuration
# To enable TLS, set secureChannelEnabled=true and specify the location of controller Java KeyStore and TrustStore files.
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.hosttracker.IfNewHostNotify;
import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
-import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.opendaylight.controller.sal.utils.IObjectReader;
import org.opendaylight.controller.sal.utils.ObjectReader;
import org.opendaylight.controller.sal.utils.ObjectWriter;
import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Static Routing feature provides the bridge between SDN and Non-SDN networks.
- *
- *
- *
*/
public class StaticRoutingImplementation implements IfNewHostNotify,
IForwardingStaticRouting, IObjectReader, IConfigurationContainerAware,
private IClusterContainerServices clusterContainerService = null;
private Set<IStaticRoutingAware> staticRoutingAware = Collections
.synchronizedSet(new HashSet<IStaticRoutingAware>());
+ private ExecutorService executor;
void setStaticRoutingAware(IStaticRoutingAware s) {
if (this.staticRoutingAware != null) {
}
}
- @SuppressWarnings("deprecation")
- private void destroyCaches() {
- if (this.clusterContainerService == null) {
- log
- .info("un-initialized clusterContainerService, can't destroy cache");
- return;
- }
-
- clusterContainerService.destroyCache("forwarding.staticrouting.routes");
- clusterContainerService
- .destroyCache("forwarding.staticrouting.configs");
- clusterContainerService
- .destroyCache("forwarding.staticrouting.configSaveEvent");
-
- }
-
@Override
public void entryCreated(Long key, String cacheName, boolean local) {
}
}
}
- private class NotifyStaticRouteThread extends Thread {
+ private class NotifyStaticRouteWorker implements Callable<Object> {
private StaticRoute staticRoute;
private boolean added;
- public NotifyStaticRouteThread(StaticRoute s, boolean update) {
+ public NotifyStaticRouteWorker(StaticRoute s, boolean update) {
this.staticRoute = s;
this.added = update;
}
- public void run() {
+ @Override
+ public Object call() throws Exception {
if (!added
|| (staticRoute.getType() == StaticRoute.NextHopType.SWITCHPORT)) {
notifyStaticRouteUpdate(staticRoute, added);
} else {
- HostNodeConnector host = hostTracker.hostQuery(staticRoute
- .getNextHopAddress());
+ InetAddress nh = staticRoute.getNextHopAddress();
+ HostNodeConnector host = hostTracker.hostQuery(nh);
if (host == null) {
- Future<HostNodeConnector> future = hostTracker
- .discoverHost(staticRoute.getNextHopAddress());
+ log.debug("Next hop {} is not present, try to discover it", nh.getHostAddress());
+ Future<HostNodeConnector> future = hostTracker.discoverHost(nh);
if (future != null) {
try {
host = future.get();
} catch (Exception e) {
- log.error("",e);
+ log.error("", e);
}
}
}
if (host != null) {
+ log.debug("Next hop {} is found", nh.getHostAddress());
staticRoute.setHost(host);
notifyStaticRouteUpdate(staticRoute, added);
+ } else {
+ log.debug("Next hop {} is still not present, try again later", nh.getHostAddress());
}
}
+ return null;
}
}
private void checkAndUpdateListeners(StaticRoute staticRoute, boolean added) {
- new NotifyStaticRouteThread(staticRoute, added).start();
+ NotifyStaticRouteWorker worker = new NotifyStaticRouteWorker(staticRoute, added);
+ try {
+ executor.submit(worker);
+ } catch (Exception e) {
+ log.error("got Exception ", e);
+ }
}
private void notifyHostUpdate(HostNodeConnector host, boolean added) {
//staticRoutes = new ConcurrentHashMap<String, StaticRoute>();
allocateCaches();
retrieveCaches();
-
+ this.executor = Executors.newFixedThreadPool(1);
if (staticRouteConfigs.isEmpty())
loadConfiguration();
log.debug("Destroy all the Static Routing Rules given we are "
+ "shutting down");
- destroyCaches();
gatewayProbeTimer.cancel();
// Clear the listener so to be ready in next life
*
*/
void stop() {
+ executor.shutdown();
}
@Override
public Status saveConfiguration() {
return this.saveConfig();
}
+
}
log.warn(logMsg, groupName);
return new Status(StatusCode.NOTACCEPTABLE, msg);
}
- int toBeRemoved = groupFlows.get(groupName).size();
+ int toBeRemoved = 0;
String error = "";
if (groupFlows.containsKey(groupName)) {
List<FlowEntryInstall> list = new ArrayList<FlowEntryInstall>(groupFlows.get(groupName));
+ toBeRemoved = list.size();
for (FlowEntryInstall entry : list) {
Status status = this.removeEntry(entry.getOriginal(), false);
if (status.isSuccess()) {
private Timer timer;
private Timer arp_refresh_timer;
private String containerName = null;
-
+ private ExecutorService executor;
private static class ARPPending {
protected InetAddress hostIP;
protected short sent_count;
timer = new Timer();
timer.schedule(new OutStandingARPHandler(), 4000, 4000);
-
+ executor = Executors.newFixedThreadPool(2);
/* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */
arp_refresh_timer = new Timer();
arp_refresh_timer.schedule(new ARPRefreshHandler(), 5000, 5000);
inactiveStaticHosts = new ConcurrentHashMap<NodeConnector, HostNodeConnector>();
}
- @SuppressWarnings("deprecation")
- private void destroyCache() {
- if (this.clusterContainerService == null) {
- logger.error("un-initialized clusterMger, can't destroy cache");
- return;
- }
- logger.debug("Destroying Cache for HostTracker");
- this.clusterContainerService.destroyCache("hostTrackerAH");
- this.clusterContainerService.destroyCache("hostTrackerIH");
- nonClusterObjectCreate();
- }
public void shutDown() {
}
@Override
public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
- ExecutorService executor = Executors.newFixedThreadPool(1);
if (executor == null) {
logger.error("discoverHost: Null executor");
return null;
*
*/
void destroy() {
- destroyCache();
}
/**
*
*/
void stop() {
+ executor.shutdown();
}
@Override
if (h != null)
return h;
hostTracker.setCallableOnPendingARP(trackedHost, this);
- latch.await();
+ Thread.sleep(2000); // wait 2sec to see if the host responds
return hostTracker.hostQuery(trackedHost);
}
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
import org.opendaylight.controller.northbound.commons.RestMessages;
import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
import org.opendaylight.controller.sal.authorization.Privilege;
@Path("/")
public class SubnetsNorthboundJAXRS {
- protected static final Logger logger = LoggerFactory
- .getLogger(SubnetsNorthboundJAXRS.class);
+ protected static final Logger logger = LoggerFactory.getLogger(SubnetsNorthboundJAXRS.class);
private String username;
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@StatusCodes({ @ResponseCode(code = 404, condition = "The containerName passed was not found") })
@TypeHint(SubnetConfigs.class)
- public SubnetConfigs listSubnets(
- @PathParam("containerName") String containerName) {
- if (!NorthboundUtils.isAuthorized(
- getUserName(), containerName, Privilege.READ, this)) {
- throw new UnauthorizedException(
- "User is not authorized to perform this operation on container "
- + containerName);
+ public SubnetConfigs listSubnets(@PathParam("containerName") String containerName) {
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation on container "
+ + containerName);
}
ISwitchManager switchManager = null;
- switchManager = (ISwitchManager) ServiceHelper.getInstance(
- ISwitchManager.class, containerName, this);
+ switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
if (switchManager == null) {
- throw new ResourceNotFoundException(
- RestMessages.NOCONTAINER.toString());
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
}
return new SubnetConfigs(switchManager.getSubnetsConfigList());
}
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@StatusCodes({
- @ResponseCode(code = 404, condition = "The containerName passed was not found"),
- @ResponseCode(code = 404, condition = "Subnet does not exist") })
- @TypeHint(SubnetConfig.class)
+ @ResponseCode(code = 404, condition = "The containerName passed was not found"),
+ @ResponseCode(code = 404, condition = "Subnet does not exist") })
+ @TypeHint(SubnetConfig.class)
public SubnetConfig listSubnet(
- @PathParam("containerName") String containerName,
- @PathParam("subnetName") String subnetName) {
+ @PathParam("containerName") String containerName,
+ @PathParam("subnetName") String subnetName) {
- if (!NorthboundUtils.isAuthorized(
- getUserName(), containerName, Privilege.READ, this)) {
- throw new UnauthorizedException(
- "User is not authorized to perform this operation on container "
- + containerName);
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation on container "
+ + containerName);
}
ISwitchManager switchManager = null;
- switchManager = (ISwitchManager) ServiceHelper.getInstance(
- ISwitchManager.class, containerName, this);
+ switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
if (switchManager == null) {
- throw new ResourceNotFoundException(
- RestMessages.NOCONTAINER.toString());
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
}
SubnetConfig res = switchManager.getSubnetConfig(subnetName);
if (res == null) {
- throw new ResourceNotFoundException(
- RestMessages.NOSUBNET.toString());
+ throw new ResourceNotFoundException(RestMessages.NOSUBNET.toString());
} else {
return res;
}
@Path("/{containerName}/{subnetName}")
@POST
@StatusCodes({
- @ResponseCode(code = 404, condition = "Invalid Data passed"),
- @ResponseCode(code = 201, condition = "Subnet added"),
- @ResponseCode(code = 500, condition = "Addition of subnet failed") })
- public Response addSubnet(@PathParam("containerName") String containerName,
- @PathParam("subnetName") String subnetName,
- @QueryParam("subnet") String subnet) {
-
- if (!NorthboundUtils.isAuthorized(
- getUserName(), containerName, Privilege.WRITE, this)) {
- throw new UnauthorizedException(
- "User is not authorized to perform this operation on container "
- + containerName);
+ @ResponseCode(code = 404, condition = "Invalid Data passed"),
+ @ResponseCode(code = 201, condition = "Subnet added"),
+ @ResponseCode(code = 500, condition = "Addition of subnet failed") })
+ public Response addSubnet(
+ @PathParam("containerName") String containerName,
+ @PathParam("subnetName") String subnetName, @QueryParam("subnet") String subnet) {
+
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation on container "
+ + containerName);
}
if (subnetName == null) {
- throw new ResourceNotFoundException(
- RestMessages.INVALIDDATA.toString());
+ throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
}
if (subnet == null) {
- throw new ResourceNotFoundException(
- RestMessages.INVALIDDATA.toString());
+ throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
}
ISwitchManager switchManager = null;
- switchManager = (ISwitchManager) ServiceHelper.getInstance(
- ISwitchManager.class, containerName, this);
+ switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
if (switchManager == null) {
- throw new ResourceNotFoundException(
- RestMessages.NOCONTAINER.toString());
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
}
- SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet,
- new ArrayList<String>(0));
+ SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet, new ArrayList<String>(0));
Status status = switchManager.addSubnet(cfgObject);
if (status.isSuccess()) {
return Response.status(Response.Status.CREATED).build();
@Path("/{containerName}/{subnetName}")
@DELETE
@StatusCodes({
- @ResponseCode(code = 404, condition = "The containerName passed was not found"),
- @ResponseCode(code = 500, condition = "Removal of subnet failed") })
+ @ResponseCode(code = 404, condition = "The containerName passed was not found"),
+ @ResponseCode(code = 500, condition = "Removal of subnet failed") })
public Response removeSubnet(
- @PathParam("containerName") String containerName,
- @PathParam("subnetName") String subnetName) {
+ @PathParam("containerName") String containerName,
+ @PathParam("subnetName") String subnetName) {
if (subnetName == null) {
- throw new ResourceNotFoundException(
- RestMessages.INVALIDDATA.toString());
+ throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
}
- if (!NorthboundUtils.isAuthorized(
- getUserName(), containerName, Privilege.WRITE, this)) {
- throw new UnauthorizedException(
- "User is not authorized to perform this operation on container "
- + containerName);
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation on container "
+ + containerName);
}
ISwitchManager switchManager = null;
- switchManager = (ISwitchManager) ServiceHelper.getInstance(
- ISwitchManager.class, containerName, this);
+ switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
if (switchManager == null) {
- throw new ResourceNotFoundException(
- RestMessages.NOCONTAINER.toString());
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
}
Status status = switchManager.removeSubnet(subnetName);
if (status.isSuccess()) {
@POST
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@StatusCodes({
- @ResponseCode(code = 202, condition = "Operation successful"),
- @ResponseCode(code = 400, condition = "Invalid request, i.e., requested changing the subnet name"),
- @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
- @ResponseCode(code = 500, condition = "Internal server error")})
+ @ResponseCode(code = 202, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Invalid request, i.e., requested changing the subnet name"),
+ @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+ @ResponseCode(code = 500, condition = "Internal server error") })
public Response modifySubnet(@PathParam("containerName") String containerName,
- @PathParam("subnetName") String name,
- @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+ @PathParam("subnetName") String name,
+ @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
- if (!NorthboundUtils.isAuthorized(getUserName(), containerName,
- Privilege.WRITE, this)) {
- throw new UnauthorizedException(
- "User is not authorized to perform this operation on container " + containerName);
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation on container "
+ + containerName);
}
- ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
- containerName, this);
+ ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+ this);
if (switchManager == null) {
throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
}
// make sure that the name matches an existing subnet and we're not
// changing the name or subnet IP/mask
- if (existingConf == null){
+ if (existingConf == null) {
// don't have a subnet by that name
return Response.status(Response.Status.NOT_FOUND).build();
- }else if( !existingConf.getName().equals(subnetConf.getName())
- || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
+ } else if (!existingConf.getName().equals(subnetConf.getName())
+ || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
// can't change the name of a subnet
return Response.status(Response.Status.BAD_REQUEST).build();
- }else{
+ } else {
// create a set for fast lookups
Set<String> newPorts = new HashSet<String>(subnetConf.getNodePorts());
// go through the current ports and (1) remove ports that aren't
// there anymore and (2) remove ports that are still there from the
// set of ports to add
- for(String s : existingConf.getNodePorts()){
- if(newPorts.contains(s)){
+ for (String s : existingConf.getNodePorts()) {
+ if (newPorts.contains(s)) {
newPorts.remove(s);
- }else{
+ } else {
Status st = switchManager.removePortsFromSubnet(name, s);
successful = successful && st.isSuccess();
}
}
// add any remaining ports
- for(String s : newPorts){
+ for (String s : newPorts) {
Status st = switchManager.addPortsToSubnet(name, s);
successful = successful && st.isSuccess();
}
}
- if(successful){
+ if (successful) {
return Response.status(Response.Status.ACCEPTED).build();
- }else{
+ } else {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
- /*
- *
- * Add or remove switch ports to a subnet POST subnets/green/sw
+ /**
*
- * @param model
+ * Add ports to a subnet
*
* @param containerName
- *
+ * Name of the Container
* @param name
+ * Name of the SubnetConfig to be modified
+ * @param subnetConfigData
+ * the {@link SubnetConfig} structure in JSON passed as a POST
+ * parameter
+ * @return If the operation is successful or not
+ */
+ @Path("/{containerName}/{subnetName}/add")
+ @POST
+ @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @StatusCodes({
+ @ResponseCode(code = 202, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Invalid request"),
+ @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+ @ResponseCode(code = 500, condition = "Internal server error") })
+ public Response addNodePorts(
+ @PathParam("containerName") String containerName,
+ @PathParam("subnetName") String name,
+ @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+
+ SubnetConfig subnetConf = subnetConfigData.getValue();
+ return addOrDeletePorts(containerName, name, subnetConf, "add");
+ }
+
+ /**
*
- * @param subnet: the subnet name name
- *
- * @param switchports: datapath ID/port list =>
- * xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
- *
- * @return
- *
- * @RequestMapping(value = "/{containerName}/{name}", method =
- * RequestMethod.POST)
- *
- * public View addSwitchports(Map<String, Object> model,
- *
- * @PathVariable(value = "containerName") String containerName,
- *
- * @PathVariable(value = "name") String name,
- *
- * @RequestParam(value = "nodeports") String nodePorts,
- *
- * @RequestParam(value = "action") String action) {
- *
- * checkDefaultDisabled(containerName); ISwitchManager switchManager = null;
- * try { BundleContext bCtx = FrameworkUtil.getBundle(this.getClass())
- * .getBundleContext();
- *
- * ServiceReference[] services = bCtx.getServiceReferences(
- * ISwitchManager.class.getName(), "(containerName=" + containerName + ")");
- *
- * if (services != null) { switchManager = (ISwitchManager)
- * bCtx.getService(services[0]); logger.debug("Switch manager reference is:"
- * + switchManager); } } catch (Exception e) {
- * logger.error("Switch Manager reference is NULL"); }
- *
- * checkContainerExists(switchManager);
- *
- * String ret; if (action.equals("add")) { ret =
- * switchManager.addPortsToSubnet(name, nodePorts); } else if
- * (action.equals("remove")) { ret =
- * switchManager.removePortsFromSubnet(name, nodePorts); } else { throw new
- * UnsupportedMediaTypeException(RestMessages.UNKNOWNACTION .toString() +
- * ": " + action); }
+ * Delete ports from a subnet
*
- * return returnViewOrThrowConflicEx(model, ret); }
+ * @param containerName
+ * Name of the Container
+ * @param name
+ * Name of the SubnetConfig to be modified
+ * @param subnetConfigData
+ * the {@link SubnetConfig} structure in JSON passed as a POST
+ * parameter
+ * @return If the operation is successful or not
*/
+ @Path("/{containerName}/{subnetName}/delete")
+ @POST
+ @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @StatusCodes({
+ @ResponseCode(code = 202, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Invalid request"),
+ @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+ @ResponseCode(code = 500, condition = "Internal server error") })
+ public Response deleteNodePorts(
+ @PathParam("containerName") String containerName,
+ @PathParam("subnetName") String name,
+ @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+
+ SubnetConfig subnetConf = subnetConfigData.getValue();
+ return addOrDeletePorts(containerName, name, subnetConf, "delete");
+ }
+
+ /**
+ *
+ * Add/Delete ports to/from a subnet
+ *
+ * @param containerName
+ * Name of the Container
+ * @param name
+ * Name of the SubnetConfig to be modified
+ * @param subnetConfig
+ * the {@link SubnetConfig} structure
+ * @param action
+ * add or delete
+ * @return If the operation is successful or not
+ */
+ private Response addOrDeletePorts(String containerName, String name, SubnetConfig subnetConf, String action) {
+
+ if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation on container "
+ + containerName);
+ }
+
+ ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+ this);
+ if (switchManager == null) {
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
+ }
+
+ SubnetConfig existingConf = switchManager.getSubnetConfig(name);
+
+ // make sure that the name matches an existing subnet and we're not
+ // changing the name or subnet IP/mask
+ if (existingConf == null) {
+ // don't have a subnet by that name
+ return Response.status(Response.Status.NOT_FOUND).build();
+ } else if (!existingConf.getName().equals(subnetConf.getName())
+ || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
+ // can't change the name of a subnet
+ return Response.status(Response.Status.BAD_REQUEST).build();
+ } else {
+ Status st;
+ boolean successful = true;
+ List<String> ports = subnetConf.getNodePorts();
+
+ if (action.equals("add")) {
+ // add new ports
+ ports.removeAll(existingConf.getNodePorts());
+ for (String port : ports) {
+ st = switchManager.addPortsToSubnet(name, port);
+ successful = successful && st.isSuccess();
+ }
+ } else if (action.equals("delete")) {
+ // delete existing ports
+ ports.retainAll(existingConf.getNodePorts());
+ for (String port : ports) {
+ st = switchManager.removePortsFromSubnet(name, port);
+ successful = successful && st.isSuccess();
+ }
+ } else {
+ return Response.status(Response.Status.BAD_REQUEST).build();
+ }
+
+ if (successful) {
+ return Response.status(Response.Status.ACCEPTED).build();
+ } else {
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+ }
+ }
+ }
}
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
private IDiscoveryListener discoveryListener = null;
private IInventoryProvider inventoryProvider = null;
private IDataPacketMux iDataPacketMux = null;
- // Newly added ports go into this list and will be served first
+ // High priority list containing newly added ports which will be served first
private List<NodeConnector> readyListHi = null;
- // Come here after served at least once
+ // List containing all the ports which will be served periodically
private List<NodeConnector> readyListLo = null;
// Staging area during quiet period
- private List<NodeConnector> waitingList = null;
+ private List<NodeConnector> stagingList = null;
// Wait for next discovery packet. The map contains the time elapsed since
// the last received LLDP frame on each node connector
- private ConcurrentMap<NodeConnector, Integer> pendingMap = null;
- // openflow edges keyed by head connector
+ private ConcurrentMap<NodeConnector, Integer> holdTime = null;
+ // Allow one more retry for newly added ports. This map contains the time
+ // period elapsed since last discovery pkt transmission on the port.
+ private ConcurrentMap<NodeConnector, Integer> elapsedTime = null;
+ // OpenFlow edges keyed by head connector
private ConcurrentMap<NodeConnector, Edge> edgeMap = null;
- // Aging entries keyed by head edge connector
+ // The map contains aging entry keyed by head connector of Production edge
private ConcurrentMap<NodeConnector, Integer> agingMap = null;
- // Production edges keyed by head edge connector
+ // Production edges keyed by head connector
private ConcurrentMap<NodeConnector, Edge> prodMap = null;
private Timer discoveryTimer;
private final static long discoveryTimerTick = 2L * 1000; // per tick in msec
private int discoveryTimerTickCount = 0; // main tick counter
// Max # of ports handled in one batch
- private int discoveryBatchMaxPorts = 500;
+ private int discoveryBatchMaxPorts;
// Periodically restart batching process
- private int discoveryBatchRestartTicks = getDiscoveryInterval();
- private int discoveryBatchPausePeriod = 5;
+ private int discoveryBatchRestartTicks;
+ private int discoveryBatchPausePeriod = 2;
// Pause after this point
- private int discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
- // Number of retries after initial timeout
- private int discoveryRetry = getDiscoveryRetry();
- private int discoveryTimeoutTicks = getDiscoveryTimeout();
- private int discoveryAgeoutTicks = getDiscoveryAgeout();
+ private int discoveryBatchPauseTicks;
+ private int discoveryTimeoutTicks;
+ private int discoveryThresholdTicks;
+ private int discoveryAgeoutTicks;
// multiple of discoveryBatchRestartTicks
private int discoveryConsistencyCheckMultiple = 2;
// CC tick counter
- private int discoveryConsistencyCheckTickCount = discoveryBatchPauseTicks;
- // # of times CC getscalled
+ private int discoveryConsistencyCheckTickCount;
+ // # of times CC gets called
private int discoveryConsistencyCheckCallingTimes = 0;
// # of cases CC corrected
private int discoveryConsistencyCheckCorrected = 0;
}
public enum DiscoveryPeriod {
- INTERVAL(300),
- TIMEOUT (60),
- AGEOUT (120);
+ INTERVAL (300),
+ AGEOUT (120),
+ THRESHOLD (30);
private int time; // sec
private int tick; // tick
return tick;
}
+ public void setTick(int tick) {
+ this.time = tick2Time(tick);
+ this.tick = tick;
+ }
+
private int time2Tick(int time) {
return (int) (time / (discoveryTimerTick / 1000));
}
+
+ private int tick2Time(int tick) {
+ return (int) (tick * (discoveryTimerTick / 1000));
+ }
}
private RawPacket createDiscoveryPacket(NodeConnector nodeConnector) {
logger.error("Caught exception ", e);
}
addEdge(edge, props);
- pendingMap.put(dstNodeConnector, 0);
logger.trace("Received discovery packet for Edge {}", edge);
return true;
}
- if (pendingMap.keySet().contains(nodeConnector)) {
+ if (holdTime.keySet().contains(nodeConnector)) {
return true;
}
- if (waitingList.contains(nodeConnector)) {
+ if (stagingList.contains(nodeConnector)) {
return true;
}
workingSet.add(nodeConnector);
removeSet.add(nodeConnector);
+
+ // Put it in the map and start the timer. It may need retry.
+ elapsedTime.put(nodeConnector, 0);
}
readyListHi.removeAll(removeSet);
}
for (NodeConnector nodeConnector : c) {
if (node.equals(nodeConnector.getNode())) {
- removeSet.add(nodeConnector);
+ Edge edge1 = edgeMap.get(nodeConnector);
+ if (edge1 != null) {
+ removeSet.add(nodeConnector);
+
+ // check reverse direction
+ Edge edge2 = edgeMap.get(edge1.getTailNodeConnector());
+ if ((edge2 != null) && node.equals(edge2.getTailNodeConnector().getNode())) {
+ removeSet.add(edge2.getHeadNodeConnector());
+ }
+ }
}
}
return removeSet;
removeSet = getRemoveSet(readyListLo, node);
readyListLo.removeAll(removeSet);
- removeSet = getRemoveSet(waitingList, node);
- waitingList.removeAll(removeSet);
+ removeSet = getRemoveSet(stagingList, node);
+ stagingList.removeAll(removeSet);
- removeSet = getRemoveSet(pendingMap.keySet(), node);
+ removeSet = getRemoveSet(holdTime.keySet(), node);
for (NodeConnector nodeConnector : removeSet) {
- pendingMap.remove(nodeConnector);
+ holdTime.remove(nodeConnector);
}
removeSet = getRemoveSet(edgeMap.keySet(), node);
private void removeDiscovery(NodeConnector nodeConnector) {
readyListHi.remove(nodeConnector);
readyListLo.remove(nodeConnector);
- waitingList.remove(nodeConnector);
- pendingMap.remove(nodeConnector);
+ stagingList.remove(nodeConnector);
+ holdTime.remove(nodeConnector);
removeEdge(nodeConnector, false);
removeProdEdge(nodeConnector);
}
private void checkTimeout() {
Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
- Set<NodeConnector> retrySet = new HashSet<NodeConnector>();
int ticks;
- Set<NodeConnector> pendingSet = pendingMap.keySet();
- if (pendingSet != null) {
- for (NodeConnector nodeConnector : pendingSet) {
- ticks = pendingMap.get(nodeConnector);
- pendingMap.put(nodeConnector, ++ticks);
- if (ticks > getDiscoveryFinalTimeoutInterval()) {
+ Set<NodeConnector> monitorSet = holdTime.keySet();
+ if (monitorSet != null) {
+ for (NodeConnector nodeConnector : monitorSet) {
+ ticks = holdTime.get(nodeConnector);
+ holdTime.put(nodeConnector, ++ticks);
+ if (ticks >= discoveryTimeoutTicks) {
// timeout the edge
removeSet.add(nodeConnector);
logger.trace("Discovery timeout {}", nodeConnector);
- } else if (ticks % discoveryTimeoutTicks == 0) {
- retrySet.add(nodeConnector);
}
}
}
removeEdge(nodeConnector);
}
- for (NodeConnector nodeConnector : retrySet) {
- transmitQ.add(nodeConnector);
+ Set<NodeConnector> retrySet = new HashSet<NodeConnector>();
+ Set<NodeConnector> ncSet = elapsedTime.keySet();
+ if ((ncSet != null) && (ncSet.size() > 0)) {
+ for (NodeConnector nodeConnector : ncSet) {
+ ticks = elapsedTime.get(nodeConnector);
+ elapsedTime.put(nodeConnector, ++ticks);
+ if (ticks >= discoveryThresholdTicks) {
+ retrySet.add(nodeConnector);
+ }
+ }
+
+ for (NodeConnector nodeConnector : retrySet) {
+ // Allow one more retry
+ readyListLo.add(nodeConnector);
+ elapsedTime.remove(nodeConnector);
+ }
}
}
if (++discoveryTimerTickCount <= discoveryBatchPauseTicks) {
for (NodeConnector nodeConnector : getWorkingSet()) {
transmitQ.add(nodeConnector);
+ // Move to staging area after it's served
+ if (!stagingList.contains(nodeConnector)) {
+ stagingList.add(nodeConnector);
+ }
}
} else if (discoveryTimerTickCount >= discoveryBatchRestartTicks) {
discoveryTimerTickCount = 0;
- for (NodeConnector nodeConnector : waitingList) {
+ for (NodeConnector nodeConnector : stagingList) {
if (!readyListLo.contains(nodeConnector)) {
readyListLo.add(nodeConnector);
}
}
- waitingList.removeAll(readyListLo);
+ stagingList.removeAll(readyListLo);
}
}
}
if (!isTracked(nodeConnector)) {
- waitingList.add(nodeConnector);
+ stagingList.add(nodeConnector);
discoveryConsistencyCheckCorrected++;
logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
continue;
// remove stale entries
removeSet.clear();
- for (NodeConnector nodeConnector : waitingList) {
+ for (NodeConnector nodeConnector : stagingList) {
if (!isEnabled(nodeConnector)) {
removeSet.add(nodeConnector);
discoveryConsistencyCheckCorrected++;
logger.debug("ConsistencyChecker: remove disabled {}", nodeConnector);
}
}
- waitingList.removeAll(removeSet);
+ stagingList.removeAll(removeSet);
// Get a snapshot of all the existing switches
Map<Long, ISwitch> switches = this.controller.getSwitches();
Node node = NodeCreator.createOFNode(sw.getId());
NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node);
if (!isTracked(nodeConnector)) {
- waitingList.add(nodeConnector);
+ stagingList.add(nodeConnector);
discoveryConsistencyCheckCorrected++;
logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
}
}
NodeConnector src = edge.getTailNodeConnector();
+ NodeConnector dst = edge.getHeadNodeConnector();
if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
- pendingMap.remove(src);
+ holdTime.put(dst, 0);
} else {
- NodeConnector dst = edge.getHeadNodeConnector();
agingMap.put(dst, 0);
}
+ elapsedTime.remove(src);
// notify
updateEdge(edge, UpdateType.ADDED, props);
* Remove OpenFlow edge
*/
private void removeEdge(NodeConnector nodeConnector, boolean stillEnabled) {
- pendingMap.remove(nodeConnector);
+ holdTime.remove(nodeConnector);
readyListLo.remove(nodeConnector);
readyListHi.remove(nodeConnector);
if (stillEnabled) {
// keep discovering
- if (!waitingList.contains(nodeConnector)) {
- waitingList.add(nodeConnector);
+ if (!stagingList.contains(nodeConnector)) {
+ stagingList.add(nodeConnector);
}
} else {
// stop it
- waitingList.remove(nodeConnector);
+ stagingList.remove(nodeConnector);
}
Edge edge = null;
private void moveToReadyListHi(NodeConnector nodeConnector) {
if (readyListLo.contains(nodeConnector)) {
readyListLo.remove(nodeConnector);
- } else if (waitingList.contains(nodeConnector)) {
- waitingList.remove(nodeConnector);
+ } else if (stagingList.contains(nodeConnector)) {
+ stagingList.remove(nodeConnector);
}
readyListHi.add(nodeConnector);
}
return discoveryConsistencyCheckMultiple * discoveryBatchRestartTicks;
}
- private int getDiscoveryFinalTimeoutInterval() {
- return (discoveryRetry + 1) * discoveryTimeoutTicks;
- }
-
@Override
public String getHelp() {
StringBuffer help = new StringBuffer();
help.append("---Topology Discovery---\n");
help.append("\t prlh - Print readyListHi entries\n");
help.append("\t prll - Print readyListLo entries\n");
- help.append("\t pwl - Print waitingList entries\n");
- help.append("\t ppl - Print pendingList entries\n");
+ help.append("\t psl - Print stagingList entries\n");
+ help.append("\t pht - Print hold time\n");
+ help.append("\t pet - Print elapsed time\n");
help.append("\t ptick - Print tick time in msec\n");
help.append("\t pcc - Print CC info\n");
help.append("\t psize - Print sizes of all the lists\n");
help.append("\t sports [ports] - Set/show max ports per batch\n");
help.append("\t spause [ticks] - Set/show pause period\n");
help.append("\t sdi [ticks] - Set/show discovery interval in ticks\n");
- help.append("\t stm [ticks] - Set/show per timeout ticks\n");
- help.append("\t sretry [count] - Set/show num of retries\n");
help.append("\t addsw <swid> - Add a switch\n");
help.append("\t remsw <swid> - Remove a switch\n");
help.append("\t page - Print aging info\n");
return help.toString();
}
+ private List<NodeConnector> sortList(Collection<NodeConnector> ncs) {
+ List<String> ncStrArray = new ArrayList<String>();
+ for (NodeConnector nc : ncs) {
+ ncStrArray.add(nc.toString());
+ }
+ Collections.sort(ncStrArray);
+
+ List<NodeConnector> sortedNodeConnectors = new ArrayList<NodeConnector>();
+ for (String ncStr : ncStrArray) {
+ sortedNodeConnectors.add(NodeConnector.fromString(ncStr));
+ }
+
+ return sortedNodeConnectors;
+ }
+
public void _prlh(CommandInterpreter ci) {
- ci.println("ReadyListHi\n");
- for (NodeConnector nodeConnector : readyListHi) {
+ ci.println("readyListHi\n");
+ for (NodeConnector nodeConnector : sortList(readyListHi)) {
if (nodeConnector == null) {
continue;
}
ci.println(nodeConnector);
}
+ ci.println("Total number of Node Connectors: " + readyListHi.size());
}
public void _prll(CommandInterpreter ci) {
- ci.println("ReadyListLo\n");
- for (NodeConnector nodeConnector : readyListLo) {
+ ci.println("readyListLo\n");
+ for (NodeConnector nodeConnector : sortList(readyListLo)) {
if (nodeConnector == null) {
continue;
}
ci.println(nodeConnector);
}
+ ci.println("Total number of Node Connectors: " + readyListLo.size());
}
- public void _pwl(CommandInterpreter ci) {
- ci.println("WaitingList\n");
- for (NodeConnector nodeConnector : waitingList) {
+ public void _psl(CommandInterpreter ci) {
+ ci.println("stagingList\n");
+ for (NodeConnector nodeConnector : sortList(stagingList)) {
if (nodeConnector == null) {
continue;
}
ci.println(nodeConnector);
}
+ ci.println("Total number of Node Connectors: " + stagingList.size());
}
- public void _ppl(CommandInterpreter ci) {
- ci.println("pendingMap\n");
- ci.println(" NodeConnector Last rx LLDP (s)");
- for (ConcurrentMap.Entry<NodeConnector, Integer> entry: pendingMap.entrySet()) {
- ci.println(entry.getKey() + "\t\t" + entry.getValue());
+ public void _pht(CommandInterpreter ci) {
+ ci.println(" NodeConnector Last rx LLDP (sec)");
+ for (ConcurrentMap.Entry<NodeConnector, Integer> entry: holdTime.entrySet()) {
+ ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
}
+ ci.println("\nSize: " + holdTime.size() + "\tTimeout: " + discoveryTimeoutTicks * (discoveryTimerTick / 1000)
+ + " sec");
+ }
+
+ public void _pet(CommandInterpreter ci) {
+ ci.println(" NodeConnector Elapsed Time (sec)");
+ for (ConcurrentMap.Entry<NodeConnector, Integer> entry: elapsedTime.entrySet()) {
+ ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
+ }
+ ci.println("\nSize: " + elapsedTime.size() + "\tThreshold: " + DiscoveryPeriod.THRESHOLD.getTime() + " sec");
}
public void _ptick(CommandInterpreter ci) {
}
public void _ptm(CommandInterpreter ci) {
- ci.println("Final timeout ticks " + getDiscoveryFinalTimeoutInterval());
- ci.println("Per timeout ticks " + discoveryTimeoutTicks);
- ci.println("Number of retries after initial timeout " + discoveryRetry);
+ ci.println("Timeout " + discoveryTimeoutTicks + " ticks, " + discoveryTimerTick / 1000 + " sec per tick.");
}
public void _psize(CommandInterpreter ci) {
ci.println("readyListLo size " + readyListLo.size() + "\n" + "readyListHi size " + readyListHi.size() + "\n"
- + "waitingList size " + waitingList.size() + "\n" + "pendingMap size " + pendingMap.size() + "\n"
+ + "stagingList size " + stagingList.size() + "\n" + "holdTime size " + holdTime.size() + "\n"
+ "edgeMap size " + edgeMap.size() + "\n" + "prodMap size " + prodMap.size() + "\n" + "agingMap size "
- + agingMap.size());
+ + agingMap.size() + "\n" + "elapsedTime size " + elapsedTime.size());
}
public void _page(CommandInterpreter ci) {
public void _spause(CommandInterpreter ci) {
String val = ci.nextArgument();
String out = "Please enter pause period less than " + discoveryBatchRestartTicks + ". Current pause period is "
- + discoveryBatchPausePeriod + " pause tick is " + discoveryBatchPauseTicks + ".";
+ + discoveryBatchPausePeriod + " ticks, pause at " + discoveryBatchPauseTicks + " ticks, "
+ + discoveryTimerTick / 1000 + " sec per tick.";
if (val != null) {
try {
int pause = Integer.parseInt(val);
if (pause < discoveryBatchRestartTicks) {
discoveryBatchPausePeriod = pause;
- discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
+ discoveryBatchPauseTicks = getDiscoveryPauseInterval();
return;
}
} catch (Exception e) {
public void _sdi(CommandInterpreter ci) {
String val = ci.nextArgument();
- String out = "Please enter discovery interval greater than " + discoveryBatchPausePeriod
- + ". Current value is " + discoveryBatchRestartTicks + ".";
+ String out = "Please enter discovery interval in ticks. Current value is " + discoveryBatchRestartTicks + " ticks, "
+ + discoveryTimerTick / 1000 + " sec per tick.";
if (val != null) {
try {
- int restart = Integer.parseInt(val);
- if (restart > discoveryBatchPausePeriod) {
- discoveryBatchRestartTicks = restart;
- discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
- return;
- }
+ int ticks = Integer.parseInt(val);
+ DiscoveryPeriod.INTERVAL.setTick(ticks);
+ discoveryBatchRestartTicks = getDiscoveryInterval();
+ discoveryBatchPauseTicks = getDiscoveryPauseInterval();
+ discoveryTimeoutTicks = getDiscoveryTimeout();
+ return;
} catch (Exception e) {
}
}
return;
}
- public void _sretry(CommandInterpreter ci) {
- String val = ci.nextArgument();
- if (val == null) {
- ci.println("Please enter number of retries. Current value is " + discoveryRetry);
- return;
- }
- try {
- discoveryRetry = Integer.parseInt(val);
- } catch (Exception e) {
- ci.println("Please enter a valid number");
- }
- return;
- }
-
- public void _stm(CommandInterpreter ci) {
- String val = ci.nextArgument();
- String out = "Please enter timeout tick value less than " + discoveryBatchRestartTicks + ". Current value is "
- + discoveryTimeoutTicks;
- if (val != null) {
- try {
- int timeout = Integer.parseInt(val);
- if (timeout < discoveryBatchRestartTicks) {
- discoveryTimeoutTicks = timeout;
- return;
- }
- } catch (Exception e) {
- }
- }
-
- ci.println(out);
- }
-
public void _addsw(CommandInterpreter ci) {
String val = ci.nextArgument();
Long sid;
readyListHi = new CopyOnWriteArrayList<NodeConnector>();
readyListLo = new CopyOnWriteArrayList<NodeConnector>();
- waitingList = new CopyOnWriteArrayList<NodeConnector>();
- pendingMap = new ConcurrentHashMap<NodeConnector, Integer>();
+ stagingList = new CopyOnWriteArrayList<NodeConnector>();
+ holdTime = new ConcurrentHashMap<NodeConnector, Integer>();
+ elapsedTime = new ConcurrentHashMap<NodeConnector, Integer>();
edgeMap = new ConcurrentHashMap<NodeConnector, Edge>();
agingMap = new ConcurrentHashMap<NodeConnector, Integer>();
prodMap = new ConcurrentHashMap<NodeConnector, Edge>();
discoverySnoopingDisableList = new CopyOnWriteArrayList<NodeConnector>();
+ discoveryBatchRestartTicks = getDiscoveryInterval();
+ discoveryBatchPauseTicks = getDiscoveryPauseInterval();
+ discoveryTimeoutTicks = getDiscoveryTimeout();
+ discoveryThresholdTicks = getDiscoveryThreshold();
+ discoveryAgeoutTicks = getDiscoveryAgeout();
+ discoveryConsistencyCheckTickCount = discoveryBatchPauseTicks;
+ discoveryBatchMaxPorts = getDiscoveryBatchMaxPorts();
+
discoveryTimer = new Timer("DiscoveryService");
discoveryTimerTask = new DiscoveryTimerTask();
transmitQ = null;
readyListHi = null;
readyListLo = null;
- waitingList = null;
- pendingMap = null;
+ stagingList = null;
+ holdTime = null;
edgeMap = null;
agingMap = null;
prodMap = null;
}
/**
- * This method returns the timeout value in waiting for response of a
- * discovery query.
+ * This method returns the timeout value in receiving subsequent discovery packets on a port.
*
* @return The discovery timeout in ticks
*/
private int getDiscoveryTimeout() {
- String timeout = System.getProperty("of.discoveryTimeout");
- return getDiscoveryTicks(DiscoveryPeriod.TIMEOUT, timeout);
+ String val = System.getProperty("of.discoveryTimeoutMultiple");
+ int multiple = 2;
+
+ if (val != null) {
+ try {
+ multiple = Integer.parseInt(val);
+ } catch (Exception e) {
+ }
+ }
+ return getDiscoveryInterval() * multiple + 3;
+ }
+
+ /**
+ * This method returns the user configurable threshold value
+ *
+ * @return The discovery threshold value in ticks
+ */
+ private int getDiscoveryThreshold() {
+ String val = System.getProperty("of.discoveryThreshold");
+ return getDiscoveryTicks(DiscoveryPeriod.THRESHOLD, val);
}
/**
}
/**
- * This method returns the number of retries after the initial discovery
- * packet is not received within the timeout period. Default is 2 times.
+ * This method returns the pause interval
*
- * @return The number of discovery retries
+ * @return The pause interval in ticks
*/
- private int getDiscoveryRetry() {
- String retry = System.getProperty("of.discoveryRetry");
- int rv = 2;
+ private int getDiscoveryPauseInterval() {
+ if (discoveryBatchRestartTicks > discoveryBatchPausePeriod) {
+ return discoveryBatchRestartTicks - discoveryBatchPausePeriod;
+ } else {
+ return discoveryBatchRestartTicks - 1;
+ }
+ }
- if (retry != null) {
+ /**
+ * This method returns the user configurable maximum number of ports handled
+ * in one discovery batch.
+ *
+ * @return The maximum number of ports
+ */
+ private int getDiscoveryBatchMaxPorts() {
+ String val = System.getProperty("of.discoveryBatchMaxPorts");
+ int ports = 1024;
+
+ if (val != null) {
try {
- rv = Integer.parseInt(retry);
+ ports = Integer.parseInt(val);
} catch (Exception e) {
}
}
-
- return rv;
+ return ports;
}
}
import org.openflow.protocol.OFPort;
import org.openflow.protocol.OFVendor;
import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionDataLayer;
import org.openflow.protocol.action.OFActionDataLayerDestination;
import org.openflow.protocol.action.OFActionDataLayerSource;
import org.openflow.protocol.action.OFActionNetworkLayerAddress;
}
}
if (match.isPresent(MatchType.NW_SRC)) {
- InetAddress address = (InetAddress) match.getField(
- MatchType.NW_SRC).getValue();
- InetAddress mask = (InetAddress) match.getField(
- MatchType.NW_SRC).getMask();
+ InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue();
+ InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask();
if (!isIPv6) {
- ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address
- .getAddress()));
- int maskLength = NetUtils
- .getSubnetMaskLength((mask == null) ? null : mask
- .getAddress());
- wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK)
- | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT);
+ ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
+ int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
+ wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_SRC_SHIFT);
} else {
((V6Match) ofMatch).setNetworkSource(address, mask);
}
}
if (match.isPresent(MatchType.NW_DST)) {
- InetAddress address = (InetAddress) match.getField(
- MatchType.NW_DST).getValue();
- InetAddress mask = (InetAddress) match.getField(
- MatchType.NW_DST).getMask();
+ InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue();
+ InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask();
if (!isIPv6) {
- ofMatch.setNetworkDestination(NetUtils
- .byteArray4ToInt(address.getAddress()));
- int maskLength = NetUtils
- .getSubnetMaskLength((mask == null) ? null : mask
- .getAddress());
- wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK)
- | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT);
+ ofMatch.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
+ int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
+ wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_DST_SHIFT);
} else {
((V6Match) ofMatch).setNetworkDestination(address, mask);
}
OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
ofAction.setDataLayerAddress(a.getDlAddress());
actionsList.add(ofAction);
- actionsLength += OFActionDataLayerSource.MINIMUM_LENGTH;
+ actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
continue;
}
if (action.getType() == ActionType.SET_DL_DST) {
OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
ofAction.setDataLayerAddress(a.getDlAddress());
actionsList.add(ofAction);
- actionsLength += OFActionDataLayerDestination.MINIMUM_LENGTH;
+ actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
continue;
}
if (action.getType() == ActionType.SET_NW_SRC) {
if (ofMatch != null) {
if (!isIPv6) {
// Compute OF1.0 Match
- if (ofMatch.getInputPort() != 0) {
+ if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
salMatch.setField(new MatchField(MatchType.IN_PORT,
NodeConnectorCreator.createNodeConnector(
ofMatch.getInputPort(), node)));
} else {
// Compute OF1.0 + IPv6 extensions Match
V6Match v6Match = (V6Match) ofMatch;
- if (v6Match.getInputPort() != 0) {
+ if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
// Mask on input port is not defined
salMatch.setField(new MatchField(MatchType.IN_PORT,
NodeConnectorCreator.createOFNodeConnector(
salMatch.setField(MatchType.DL_VLAN_PR, v6Match
.getDataLayerVirtualLanPriorityCodePoint());
}
+ // V6Match may carry IPv4 address
if (v6Match.getNetworkSrc() != null) {
salMatch.setField(MatchType.NW_SRC,
v6Match.getNetworkSrc(),
v6Match.getNetworkSourceMask());
+ } else if (v6Match.getNetworkSource() != 0) {
+ salMatch.setField(MatchType.NW_SRC, NetUtils
+ .getInetAddress(v6Match.getNetworkSource()),
+ NetUtils.getInetNetworkMask(
+ v6Match.getNetworkSourceMaskLen(),
+ false));
}
+ // V6Match may carry IPv4 address
if (v6Match.getNetworkDest() != null) {
salMatch.setField(MatchType.NW_DST,
v6Match.getNetworkDest(),
v6Match.getNetworkDestinationMask());
+ } else if (v6Match.getNetworkDestination() != 0) {
+ salMatch.setField(MatchType.NW_DST,
+ NetUtils.getInetAddress(v6Match
+ .getNetworkDestination()),
+ NetUtils.getInetNetworkMask(
+ v6Match.getNetworkDestinationMaskLen(),
+ false));
}
if (v6Match.getNetworkTypeOfService() != 0) {
int dscp = NetUtils.getUnsignedByte(v6Match
package org.opendaylight.controller.protocol_plugin.openflow.internal;
+import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener;
import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimInternalListener;
import org.opendaylight.controller.sal.core.Actions;
import org.opendaylight.controller.sal.core.Buffers;
import org.opendaylight.controller.sal.core.Capabilities;
-import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.core.ContainerFlow;
import org.opendaylight.controller.sal.core.Description;
import org.opendaylight.controller.sal.core.IContainerListener;
import org.opendaylight.controller.sal.core.MacAddress;
import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.Node.NodeIDType;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.core.Tables;
private IController controller = null;
private final ConcurrentMap<String, IInventoryShimInternalListener> inventoryShimInternalListeners = new ConcurrentHashMap<String, IInventoryShimInternalListener>();
private final List<IInventoryShimExternalListener> inventoryShimExternalListeners = new CopyOnWriteArrayList<IInventoryShimExternalListener>();
- private final ConcurrentMap<NodeConnector, List<String>> containerMap = new ConcurrentHashMap<NodeConnector, List<String>>();
+ private final ConcurrentMap<NodeConnector, Set<String>> nodeConnectorContainerMap = new ConcurrentHashMap<NodeConnector, Set<String>>();
+ private final ConcurrentMap<Node, Set<String>> nodeContainerMap = new ConcurrentHashMap<Node, Set<String>>();
+ private final ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorProps = new ConcurrentHashMap<NodeConnector, Set<Property>>();
+ private final ConcurrentMap<Node, Set<Property>> nodeProps = new ConcurrentHashMap<Node, Set<Property>>();
void setController(IController s) {
this.controller = s;
this.controller.removeSwitchStateListener(this);
this.inventoryShimInternalListeners.clear();
- this.containerMap.clear();
+ this.nodeConnectorContainerMap.clear();
+ this.nodeContainerMap.clear();
this.controller = null;
}
Node node = NodeCreator.createOFNode(sw.getId());
NodeConnector nodeConnector = PortConverter.toNodeConnector(
m.getDesc().getPortNumber(), node);
+ // get node connector properties
+ Set<Property> props = InventoryServiceHelper.OFPortToProps(m.getDesc());
UpdateType type = null;
if (m.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
type = UpdateType.ADDED;
+ nodeConnectorProps.put(nodeConnector, props);
} else if (m.getReason() == (byte) OFPortReason.OFPPR_DELETE.ordinal()) {
type = UpdateType.REMOVED;
+ nodeConnectorProps.remove(nodeConnector);
} else if (m.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
type = UpdateType.CHANGED;
+ nodeConnectorProps.put(nodeConnector, props);
}
logger.trace("handlePortStatusMessage {} type {}", nodeConnector, type);
if (type != null) {
- // get node connector properties
- Set<Property> props = InventoryServiceHelper.OFPortToProps(m.getDesc());
notifyInventoryShimListener(nodeConnector, type, props);
}
}
Map<NodeConnector, Set<Property>> ncProps = InventoryServiceHelper
.OFSwitchToProps(sw);
for (Map.Entry<NodeConnector, Set<Property>> entry : ncProps.entrySet()) {
+ Set<Property> props = new HashSet<Property>();
+ Set<Property> prop = entry.getValue();
+ if (prop != null) {
+ props.addAll(prop);
+ }
+ nodeConnectorProps.put(entry.getKey(), props);
notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED,
entry.getValue());
}
}
@Override
- public void nodeConnectorUpdated(String containerName, NodeConnector p,
- UpdateType t) {
- logger.debug("nodeConnectorUpdated: {} type {} for container {}",
- new Object[] { p, t, containerName });
- if (this.containerMap == null) {
- logger.error("containerMap is NULL");
- return;
+ public void nodeConnectorUpdated(String containerName, NodeConnector nc, UpdateType t) {
+ logger.debug("nodeConnectorUpdated: {} type {} for container {}", new Object[] { nc, t, containerName });
+ Node node = nc.getNode();
+ Set<String> ncContainers = this.nodeConnectorContainerMap.get(nc);
+ Set<String> nodeContainers = this.nodeContainerMap.get(node);
+ if (ncContainers == null) {
+ ncContainers = new CopyOnWriteArraySet<String>();
}
- List<String> containers = this.containerMap.get(p);
- if (containers == null) {
- containers = new CopyOnWriteArrayList<String>();
+ if (nodeContainers == null) {
+ nodeContainers = new CopyOnWriteArraySet<String>();
}
- boolean updateMap = false;
+ boolean notifyNodeUpdate = false;
+
switch (t) {
case ADDED:
- if (!containers.contains(containerName)) {
- containers.add(containerName);
- updateMap = true;
+ if (ncContainers.add(containerName)) {
+ this.nodeConnectorContainerMap.put(nc, ncContainers);
+ }
+ if (nodeContainers.add(containerName)) {
+ this.nodeContainerMap.put(node, nodeContainers);
+ notifyNodeUpdate = true;
}
break;
case REMOVED:
- if (containers.contains(containerName)) {
- containers.remove(containerName);
- updateMap = true;
+ if (ncContainers.remove(containerName)) {
+ if (ncContainers.isEmpty()) {
+ // Do cleanup to reduce memory footprint if no
+ // elements to be tracked
+ this.nodeConnectorContainerMap.remove(nc);
+ } else {
+ this.nodeConnectorContainerMap.put(nc, ncContainers);
+ }
+ }
+ boolean nodeContainerUpdate = true;
+ for (NodeConnector ncContainer : nodeConnectorContainerMap.keySet()) {
+ if ((ncContainer.getNode().equals(node)) && (nodeConnectorContainerMap.get(ncContainer).contains(containerName))) {
+ nodeContainerUpdate = false;
+ break;
+ }
+ }
+ if (nodeContainerUpdate) {
+ nodeContainers.remove(containerName);
+ notifyNodeUpdate = true;
+ if (nodeContainers.isEmpty()) {
+ this.nodeContainerMap.remove(node);
+ } else {
+ this.nodeContainerMap.put(node, nodeContainers);
+ }
}
break;
case CHANGED:
break;
}
- if (updateMap) {
- if (containers.isEmpty()) {
- // Do cleanup to reduce memory footprint if no
- // elements to be tracked
- this.containerMap.remove(p);
- } else {
- this.containerMap.put(p, containers);
- }
- }
+ Set<Property> nodeProp = nodeProps.get(node);
+ if (nodeProp == null) {
+ return;
+ }
+ Set<Property> ncProp = nodeConnectorProps.get(nc);
// notify InventoryService
- notifyInventoryShimInternalListener(containerName, p, t, null);
- notifyInventoryShimInternalListener(containerName, p.getNode(), t, null);
+ notifyInventoryShimInternalListener(containerName, nc, t, ncProp);
+
+ if (notifyNodeUpdate) {
+ notifyInventoryShimInternalListener(containerName, node, t, nodeProp);
+ }
}
private void notifyInventoryShimExternalListener(Node node,
/*
* Notify all internal and external listeners
*/
- private void notifyInventoryShimListener(NodeConnector nodeConnector,
- UpdateType type, Set<Property> props) {
- // Always notify default InventoryService. Store properties in default
- // one.
- notifyInventoryShimInternalListener(GlobalConstants.DEFAULT.toString(),
- nodeConnector, type, props);
-
- // Now notify other containers
- List<String> containers = containerMap.get(nodeConnector);
- if (containers != null) {
- for (String container : containers) {
- // no property stored in container components.
- notifyInventoryShimInternalListener(container, nodeConnector,
- type, null);
- }
+ private void notifyInventoryShimListener(NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
+ // notify other containers
+ Set<String> containers = (nodeConnectorContainerMap.get(nodeConnector) == null) ? new HashSet<String>()
+ : new HashSet<String>(nodeConnectorContainerMap.get(nodeConnector));
+ containers.add(GlobalConstants.DEFAULT.toString());
+ for (String container : containers) {
+ notifyInventoryShimInternalListener(container, nodeConnector, type, props);
}
// Notify DiscoveryService
/*
* Notify all internal and external listeners
*/
- private void notifyInventoryShimListener(Node node, UpdateType type,
- Set<Property> props) {
- switch (type) {
- case ADDED:
- // Notify only the default Inventory Service
- IInventoryShimInternalListener inventoryShimDefaultListener = inventoryShimInternalListeners
- .get(GlobalConstants.DEFAULT.toString());
- if (inventoryShimDefaultListener != null) {
- inventoryShimDefaultListener.updateNode(node, type, props);
- }
- break;
- case REMOVED:
- // Notify all Inventory Service containers
- for (IInventoryShimInternalListener inventoryShimInternalListener : inventoryShimInternalListeners
- .values()) {
- inventoryShimInternalListener.updateNode(node, type, null);
- }
- break;
- case CHANGED:
- // Notify only the default Inventory Service
- inventoryShimDefaultListener = inventoryShimInternalListeners
- .get(GlobalConstants.DEFAULT.toString());
- if (inventoryShimDefaultListener != null) {
- inventoryShimDefaultListener.updateNode(node, type, props);
- }
- break;
- default:
- break;
+ private void notifyInventoryShimListener(Node node, UpdateType type, Set<Property> props) {
+ // Now notify other containers
+ Set<String> containers = (nodeContainerMap.get(node) == null) ? new HashSet<String>() : new HashSet<String>(
+ nodeContainerMap.get(node));
+ containers.add(GlobalConstants.DEFAULT.toString());
+ for (String container : containers) {
+ notifyInventoryShimInternalListener(container, node, type, props);
}
// Notify external listener
props.add(b);
}
+ nodeProps.put(node, props);
// Notify all internal and external listeners
notifyInventoryShimListener(node, type, props);
}
private void removeNode(ISwitch sw) {
- Node node;
- try {
- node = new Node(NodeIDType.OPENFLOW, sw.getId());
- } catch (ConstructionException e) {
- logger.error("{}", e.getMessage());
+ Node node = NodeCreator.createOFNode(sw.getId());
+ if(node == null) {
return;
}
-
+ removeNodeConnectorProps(node);
+ nodeProps.remove(node);
UpdateType type = UpdateType.REMOVED;
-
// Notify all internal and external listeners
notifyInventoryShimListener(node, type, null);
}
}
}
+ private void removeNodeConnectorProps(Node node) {
+ List<NodeConnector> ncList = new ArrayList<NodeConnector>();
+ for (NodeConnector nc : nodeConnectorProps.keySet()) {
+ if (nc.getNode().equals(node)) {
+ ncList.add(nc);
+ }
+ }
+ for (NodeConnector nc : ncList) {
+ nodeConnectorProps.remove(nc);
+ }
+ }
+
@Override
public void descriptionStatisticsRefreshed(Long switchId, List<OFStatistics> descriptionStats) {
Node node = NodeCreator.createOFNode(switchId);
}
}
+ private short getStatsQueueSize() {
+ String statsQueueSizeStr = System.getProperty("of.statsQueueSize");
+ short statsQueueSize = INITIAL_SIZE;
+ if (statsQueueSizeStr != null) {
+ try {
+ statsQueueSize = Short.parseShort(statsQueueSizeStr);
+ if (statsQueueSize <= 0) {
+ statsQueueSize = INITIAL_SIZE;
+ }
+ } catch (Exception e) {
+ }
+ }
+ return statsQueueSize;
+ }
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
portStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
tableStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
dummyList = new ArrayList<OFStatistics>(1);
+ pendingStatsRequests = new LinkedBlockingQueue<StatsRequest>(getStatsQueueSize());
statisticsTimerTicks = new ConcurrentHashMap<Long, StatisticsTicks>(INITIAL_SIZE);
- pendingStatsRequests = new LinkedBlockingQueue<StatsRequest>(INITIAL_SIZE);
switchPortStatsUpdated = new LinkedBlockingQueue<Long>(INITIAL_SIZE);
switchSupportsVendorExtStats = new ConcurrentHashMap<Long, Boolean>(INITIAL_SIZE);
txRates = new HashMap<Long, Map<Short, TxRates>>(INITIAL_SIZE);
public class V6Match extends OFMatch implements Cloneable {
private static final Logger logger = LoggerFactory.getLogger(V6Match.class);
private static final long serialVersionUID = 1L;
- protected InetAddress nwSrc;
- protected InetAddress nwDst;
+ protected Inet6Address nwSrc;
+ protected Inet6Address nwDst;
protected short inputPortMask;
protected byte[] dataLayerSourceMask;
protected byte[] dataLayerDestinationMask;
protected short dataLayerTypeMask;
protected byte networkTypeOfServiceMask;
protected byte networkProtocolMask;
- protected InetAddress networkSourceMask;
- protected InetAddress networkDestinationMask;
protected short transportSourceMask;
protected short transportDestinationMask;
protected short srcIPv6SubnetMaskbits;
this.dataLayerTypeMask = 0;
this.dataLayerVirtualLanMask = 0;
this.dataLayerVirtualLanPriorityCodePointMask = 0;
- this.networkDestinationMask = null;
- this.networkSourceMask = null;
this.networkTypeOfServiceMask = 0;
this.networkProtocolMask = 0;
this.transportSourceMask = 0;
this.match_len = 0;
this.pad_size = 0;
- this.networkSourceMask = null;
if (match.getNetworkSource() != 0) {
- InetAddress address = null;
- try {
- address = InetAddress.getByAddress(ByteBuffer.allocate(4)
- .putInt(match.getNetworkSource()).array());
- } catch (UnknownHostException e) {
- logger.error("",e);
- }
- this.setNetworkSource(address, null);
+ InetAddress address = NetUtils.getInetAddress(match.getNetworkSource());
+ InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false);
+ this.setNetworkDestination(address, mask);
} else {
- this.nwSrc = null;
this.nwSrcState = MatchFieldState.MATCH_ABSENT;
}
- this.networkDestinationMask = null;
if (match.getNetworkDestination() != 0) {
- InetAddress address = null;
- try {
- address = InetAddress.getByAddress(ByteBuffer.allocate(4)
- .putInt(match.getNetworkDestination()).array());
- } catch (UnknownHostException e) {
- logger.error("",e);
- }
- this.setNetworkDestination(address, null);
+ InetAddress address = NetUtils.getInetAddress(match.getNetworkDestination());
+ InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkDestinationMaskLen(), false);
+ this.setNetworkDestination(address, mask);
} else {
- this.nwDst = null;
this.nwDstState = MatchFieldState.MATCH_ABSENT;
}
@Override
public void fromString(String match) throws IllegalArgumentException {
if (match.equals("") || match.equalsIgnoreCase("any")
- || match.equalsIgnoreCase("all") || match.equals("[]"))
+ || match.equalsIgnoreCase("all") || match.equals("[]")) {
match = "OFMatch[]";
+ }
String[] tokens = match.split("[\\[,\\]]");
String[] values;
int initArg = 0;
- if (tokens[0].equals("OFMatch"))
+ if (tokens[0].equals("OFMatch")) {
initArg = 1;
+ }
this.wildcards = OFPFW_ALL;
int i;
for (i = initArg; i < tokens.length; i++) {
values = tokens[i].split("=");
- if (values.length != 2)
+ if (values.length != 2) {
throw new IllegalArgumentException("Token " + tokens[i]
+ " does not have form 'key=value' parsing " + match);
+ }
values[0] = values[0].toLowerCase(); // try to make this case insens
if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
this.inputPort = U16.t(Integer.valueOf(values[1]));
this.wildcards &= ~OFPFW_DL_SRC;
} else if (values[0].equals(STR_DL_TYPE)
|| values[0].equals("eth_type")) {
- if (values[1].startsWith("0x"))
+ if (values[1].startsWith("0x")) {
this.dataLayerType = U16.t(Integer.valueOf(values[1]
.replaceFirst("0x", ""), 16));
- else
+ } else {
this.dataLayerType = U16.t(Integer.valueOf(values[1]));
+ }
ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
match_len += 6;
} else if (values[0].equals(STR_DL_VLAN)) {
} else if (values[0].equals(STR_NW_DST)
|| values[0].equals("ip_dst")) {
try {
+ InetAddress address = null;
+ InetAddress mask = null;
if (values[1].contains("/")) {
- String ipv6addr_wmask[] = values[1].split("/");
- this.nwDst = InetAddress.getByName(ipv6addr_wmask[0]);
- this.dstIPv6SubnetMaskbits = Short
- .valueOf(ipv6addr_wmask[1]);
- nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- match_len += 36;
+ String addressString[] = values[1].split("/");
+ address = InetAddress.getByName(addressString[0]);
+ int masklen = Integer.valueOf(addressString[1]);
+ mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
} else {
- this.nwDst = InetAddress.getByName(values[1]);
- nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 20;
+ address = InetAddress.getByName(values[1]);
}
+ this.setNetworkDestination(address, mask);
} catch (UnknownHostException e) {
logger.error("",e);
}
} else if (values[0].equals(STR_NW_SRC)
|| values[0].equals("ip_src")) {
try {
+ InetAddress address = null;
+ InetAddress mask = null;
if (values[1].contains("/")) {
- String ipv6addr_wmask[] = values[1].split("/");
- this.nwSrc = InetAddress.getByName(ipv6addr_wmask[0]);
- this.srcIPv6SubnetMaskbits = Short
- .valueOf(ipv6addr_wmask[1]);
- nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- match_len += 36;
+ String addressString[] = values[1].split("/");
+ address = InetAddress.getByName(addressString[0]);
+ int masklen = Integer.valueOf(addressString[1]);
+ mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
} else {
- this.nwSrc = InetAddress.getByName(values[1]);
- nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- match_len += 20;
+ address = InetAddress.getByName(values[1]);
}
+ this.setNetworkSource(address, mask);
} catch (UnknownHostException e) {
logger.error("",e);
}
this.transportSource = U16.t(Integer.valueOf(values[1]));
tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
match_len += 6;
- } else
+ } else {
throw new IllegalArgumentException("unknown token " + tokens[i]
+ " parsing " + match);
+ }
}
/*
}
private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) {
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+ if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
/*
* mask is not allowed for inport port
*/
return;
+ }
super.setInputPort(data.getShort());
this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match
private void readDataLinkDestination(ByteBuffer data, int nxmLen,
boolean hasMask) {
if (hasMask) {
- if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6))
+ if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) {
return;
- else {
+ } else {
byte[] bytes = new byte[6];
data.get(bytes);
super.setDataLayerDestination(bytes);
this.match_len += 16;
}
} else {
- if ((nxmLen != 6) || (data.remaining() < 6))
+ if ((nxmLen != 6) || (data.remaining() < 6)) {
return;
- else {
+ } else {
byte[] bytes = new byte[6];
data.get(bytes);
super.setDataLayerDestination(bytes);
/*
* mask is not allowed in data link source
*/
- if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask))
+ if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) {
return;
+ }
byte[] bytes = new byte[6];
data.get(bytes);
super.setDataLayerSource(bytes);
/*
* mask is not allowed in ethertype
*/
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+ if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
return;
+ }
super.setDataLayerType(data.getShort());
this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match
private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
short vlan_mask = 0xfff;
if (hasMask) {
- if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2))
+ if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
return;
- else {
+ } else {
short vlan = data.getShort();
vlan &= vlan_mask;
super.setDataLayerVirtualLan(vlan);
this.wildcards ^= (1 << 20);
}
} else {
- if ((nxmLen != 2) || (data.remaining() < 2))
+ if ((nxmLen != 2) || (data.remaining() < 2)) {
return;
- else {
+ } else {
short vlan = data.getShort();
vlan &= vlan_mask;
super.setDataLayerVirtualLan(vlan);
/*
* mask is not allowed in IP TOS
*/
- if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask))
+ if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
return;
+ }
super.setNetworkTypeOfService(data.get());
this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 5;
/*
* mask is not allowed in IP protocol
*/
- if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask))
+ if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
return;
+ }
super.setNetworkProtocol(data.get());
this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 5;
private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) {
if (hasMask) {
- if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4))
+ if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
return;
- else {
+ } else {
byte[] sbytes = new byte[4];
data.get(sbytes);
- try {
- this.nwSrc = InetAddress.getByAddress(sbytes);
- } catch (UnknownHostException e) {
- return;
- }
+ // For compatibility, let's set the IPv4 in the parent OFMatch
+ int address = NetUtils.byteArray4ToInt(sbytes);
+ super.setNetworkSource(address);
byte[] mbytes = new byte[4];
data.get(mbytes);
- try {
- this.networkSourceMask = InetAddress.getByAddress(mbytes);
- } catch (UnknownHostException e) {
- return;
- }
this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
this.match_len += 12;
int prefixlen = getNetworkMaskPrefixLength(mbytes);
this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match
-
}
} else {
- if ((nxmLen != 4) || (data.remaining() < 4))
+ if ((nxmLen != 4) || (data.remaining() < 4)) {
return;
- else {
+ } else {
byte[] sbytes = new byte[4];
data.get(sbytes);
- try {
- this.nwSrc = InetAddress.getByAddress(sbytes);
- } catch (UnknownHostException e) {
- return;
- }
+ // For compatibility, let's also set the IPv4 in the parent OFMatch
+ int address = NetUtils.byteArray4ToInt(sbytes);
+ super.setNetworkSource(address);
this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 8;
this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
if (hasMask) {
- if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4))
+ if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
return;
- else {
+ } else {
byte[] dbytes = new byte[4];
data.get(dbytes);
- try {
- this.nwDst = InetAddress.getByAddress(dbytes);
- } catch (UnknownHostException e) {
- return;
- }
+ // For compatibility, let's also set the IPv4 in the parent OFMatch
+ int address = NetUtils.byteArray4ToInt(dbytes);
+ super.setNetworkDestination(address);
byte[] mbytes = new byte[4];
data.get(mbytes);
- try {
- this.networkDestinationMask = InetAddress
- .getByAddress(mbytes);
- } catch (UnknownHostException e) {
- return;
- }
this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
this.match_len += 12;
int prefixlen = getNetworkMaskPrefixLength(mbytes);
this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0 Match
}
} else {
- if ((nxmLen != 4) || (data.remaining() < 4))
+ if ((nxmLen != 4) || (data.remaining() < 4)) {
return;
- else {
+ } else {
byte[] dbytes = new byte[4];
data.get(dbytes);
- try {
- this.nwDst = InetAddress.getByAddress(dbytes);
- } catch (UnknownHostException e) {
- return;
- }
+ int address = NetUtils.byteArray4ToInt(dbytes);
+ super.setNetworkDestination(address);
this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
this.match_len += 8;
/*
* mask is not allowed in TCP SRC
*/
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+ if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
return;
+ }
super.setTransportSource(data.getShort());
this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 6;
/*
* mask is not allowed in TCP DST
*/
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+ if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
return;
+ }
super.setTransportDestination(data.getShort());
this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 6;
/*
* mask is not allowed in UDP SRC
*/
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+ if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
return;
+ }
super.setTransportSource(data.getShort());
this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 6;
/*
* mask is not allowed in UDP DST
*/
- if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+ if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
return;
+ }
super.setTransportDestination(data.getShort());
this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
this.match_len += 6;
private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) {
if (hasMask) {
- if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16))
+ if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
return;
- else {
+ } else {
byte[] sbytes = new byte[16];
data.get(sbytes);
try {
- this.nwSrc = InetAddress.getByAddress(sbytes);
+ this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
} catch (UnknownHostException e) {
return;
}
byte[] mbytes = new byte[16];
data.get(mbytes);
- try {
- this.networkSourceMask = InetAddress.getByAddress(mbytes);
- } catch (UnknownHostException e) {
- return;
- }
+ this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
this.match_len += 36;
}
} else {
- if ((nxmLen != 16) || (data.remaining() < 16))
+ if ((nxmLen != 16) || (data.remaining() < 16)) {
return;
- else {
+ } else {
byte[] sbytes = new byte[16];
data.get(sbytes);
try {
- this.nwSrc = InetAddress.getByAddress(sbytes);
+ this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
} catch (UnknownHostException e) {
return;
}
private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
if (hasMask) {
- if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16))
+ if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
return;
- else {
+ } else {
byte[] dbytes = new byte[16];
data.get(dbytes);
try {
- this.nwDst = InetAddress.getByAddress(dbytes);
+ this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
} catch (UnknownHostException e) {
return;
}
byte[] mbytes = new byte[16];
data.get(mbytes);
- try {
- this.networkDestinationMask = InetAddress
- .getByAddress(mbytes);
- } catch (UnknownHostException e) {
- return;
- }
+ this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
this.match_len += 36;
}
} else {
- if ((nxmLen != 16) || (data.remaining() < 16))
+ if ((nxmLen != 16) || (data.remaining() < 16)) {
return;
- else {
+ } else {
byte[] dbytes = new byte[16];
data.get(dbytes);
try {
- this.nwDst = InetAddress.getByAddress(dbytes);
+ this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
} catch (UnknownHostException e) {
return;
}
+ ", dataLayerTypeMask=" + dataLayerTypeMask
+ ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
+ ", networkProtocolMask=" + networkProtocolMask
- + ", networkSourceMask=" + networkSourceMask
- + ", networkDestinationMask=" + networkDestinationMask
+ ", transportSourceMask=" + transportSourceMask
+ ", transportDestinationMask=" + transportDestinationMask
+ ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits
V6Match ret = (V6Match) super.clone();
try {
if (this.nwSrc != null) {
- ret.nwSrc = InetAddress.getByAddress(this.nwSrc.getAddress());
+ ret.nwSrc = (Inet6Address) InetAddress.getByAddress(this.nwSrc.getAddress());
}
if (this.nwDst != null) {
- ret.nwDst = InetAddress.getByAddress(this.nwDst.getAddress());
+ ret.nwDst = (Inet6Address) InetAddress.getByAddress(this.nwDst.getAddress());
}
return ret;
} catch (UnknownHostException e) {
* @return
*/
- public InetAddress getNetworkDest() {
+ public Inet6Address getNetworkDest() {
return this.nwDst;
}
- /**
- * Get nw_src
- *
- * @return
- */
-
- public void setNetworkSrc(InetAddress address) {
- nwSrc = address;
- }
-
- /**
- * Set nw_dst
- *
- * @return
- */
-
- public void setNetworkDest(InetAddress address) {
- nwDst = address;
- }
-
/**
* Set nw_src
*
* @return
*/
- public InetAddress getNetworkSrc() {
+ public Inet6Address getNetworkSrc() {
return this.nwSrc;
}
this.match_len += 5;
}
- public InetAddress getNetworkSourceMask() {
- return networkSourceMask;
+ public Inet6Address getNetworkSourceMask() {
+ return (this.nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
+ this.srcIPv6SubnetMaskbits, true) : null;
}
public void setNetworkSource(InetAddress address, InetAddress mask) {
- this.nwSrc = address;
- if (mask == null) {
- this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+ if (address instanceof Inet6Address) {
+ this.nwSrc = (Inet6Address) address;
+ if (mask == null) {
+ this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
+ this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+ } else {
+ this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
+ this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+ }
} else {
- this.networkSourceMask = mask;
- this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+ super.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
+ this.wildcards ^= (((1 << 6) - 1) << 8);
+ if (mask == null) {
+ this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
+ this.match_len += 8;
+ } else {
+ this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.match_len += 12;
+ this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 8);
+ }
}
}
- public InetAddress getNetworkDestinationMask() {
- return networkDestinationMask;
+ public Inet6Address getNetworkDestinationMask() {
+ return (this.nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
+ this.dstIPv6SubnetMaskbits, true) : null;
}
public void setNetworkDestination(InetAddress address, InetAddress mask) {
- this.nwDst = address;
- if (mask == null) {
- this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
- this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+ if (address instanceof Inet6Address) {
+ this.nwDst = (Inet6Address) address;
+ if (mask == null) {
+ this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
+ this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+ } else {
+ this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
+ this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+ }
} else {
- this.networkDestinationMask = mask;
- this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
- this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+ this.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
+ this.wildcards ^= (((1 << 6) - 1) << 14);
+ if (mask == null) {
+ this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
+ this.match_len += 8;
+ } else {
+ this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+ this.match_len += 12;
+ this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 14);
+ }
}
}
result = prime * result + inputPortMask;
result = prime * result + ((inputPortState == null) ? 0 : inputPortState.hashCode());
result = prime * result + match_len;
- result = prime * result + ((networkDestinationMask == null) ? 0 : networkDestinationMask.hashCode());
result = prime * result + networkProtocolMask;
- result = prime * result + ((networkSourceMask == null) ? 0 : networkSourceMask.hashCode());
result = prime * result + networkTypeOfServiceMask;
result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
result = prime * result + ((nwDstState == null) ? 0 : nwDstState.hashCode());
@Override
public boolean equals(Object obj) {
- if (this == obj)
+ if (this == obj) {
return true;
- if (!super.equals(obj))
+ }
+ if (!super.equals(obj)) {
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()) {
return false;
+ }
V6Match other = (V6Match) obj;
- if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask))
+ if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) {
return false;
- if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask))
- return false;
- if (dataLayerTypeMask != other.dataLayerTypeMask)
- return false;
- if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask)
+ }
+ if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) {
return false;
- if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask)
+ }
+ if (dataLayerTypeMask != other.dataLayerTypeMask) {
return false;
- if (dlDestState != other.dlDestState)
+ }
+ if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask) {
return false;
- if (dlSourceState != other.dlSourceState)
+ }
+ if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask) {
return false;
- if (dlVlanState != other.dlVlanState)
+ }
+ if (dlDestState != other.dlDestState) {
return false;
- if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits)
+ }
+ if (dlSourceState != other.dlSourceState) {
return false;
- if (ethTypeState != other.ethTypeState)
+ }
+ if (dlVlanState != other.dlVlanState) {
return false;
- if (inputPortMask != other.inputPortMask)
+ }
+ if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
return false;
- if (inputPortState != other.inputPortState)
+ }
+ if (ethTypeState != other.ethTypeState) {
return false;
- if (match_len != other.match_len)
+ }
+ if (inputPortMask != other.inputPortMask) {
return false;
- if (networkDestinationMask == null) {
- if (other.networkDestinationMask != null)
- return false;
- } else if (!networkDestinationMask.equals(other.networkDestinationMask))
+ }
+ if (inputPortState != other.inputPortState) {
return false;
- if (networkProtocolMask != other.networkProtocolMask)
+ }
+ if (match_len != other.match_len) {
return false;
- if (networkSourceMask == null) {
- if (other.networkSourceMask != null)
- return false;
- } else if (!networkSourceMask.equals(other.networkSourceMask))
+ }
+ if (networkProtocolMask != other.networkProtocolMask) {
return false;
- if (networkTypeOfServiceMask != other.networkTypeOfServiceMask)
+ }
+ if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) {
return false;
+ }
if (nwDst == null) {
- if (other.nwDst != null)
+ if (other.nwDst != null) {
return false;
- } else if (!nwDst.equals(other.nwDst))
+ }
+ } else if (!nwDst.equals(other.nwDst)) {
return false;
- if (nwDstState != other.nwDstState)
+ }
+ if (nwDstState != other.nwDstState) {
return false;
- if (nwProtoState != other.nwProtoState)
+ }
+ if (nwProtoState != other.nwProtoState) {
return false;
+ }
if (nwSrc == null) {
- if (other.nwSrc != null)
+ if (other.nwSrc != null) {
return false;
- } else if (!nwSrc.equals(other.nwSrc))
+ }
+ } else if (!nwSrc.equals(other.nwSrc)) {
return false;
- if (nwSrcState != other.nwSrcState)
+ }
+ if (nwSrcState != other.nwSrcState) {
return false;
- if (nwTosState != other.nwTosState)
+ }
+ if (nwTosState != other.nwTosState) {
return false;
- if (pad_size != other.pad_size)
+ }
+ if (pad_size != other.pad_size) {
return false;
- if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits)
+ }
+ if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) {
return false;
- if (tpDstState != other.tpDstState)
+ }
+ if (tpDstState != other.tpDstState) {
return false;
- if (tpSrcState != other.tpSrcState)
+ }
+ if (tpSrcState != other.tpSrcState) {
return false;
- if (transportDestinationMask != other.transportDestinationMask)
+ }
+ if (transportDestinationMask != other.transportDestinationMask) {
return false;
- if (transportSourceMask != other.transportSourceMask)
+ }
+ if (transportSourceMask != other.transportSourceMask) {
return false;
+ }
return true;
}
}
match3.getDataLayerSource()));
Assert.assertTrue(Arrays.equals(match.getDataLayerDestination(),
match3.getDataLayerDestination()));
- Assert.assertTrue(match.getNetworkSrc().equals(match3.getNetworkSrc()));
- Assert.assertTrue(match.getNetworkDest()
- .equals(match3.getNetworkDest()));
+ Assert.assertNull(match.getNetworkSrc());
+ Assert.assertNull(match3.getNetworkSrc());
+ Assert.assertNull(match.getNetworkDest());
+ Assert.assertNull(match3.getNetworkDest());
Assert.assertTrue(match.getDataLayerVirtualLan() == match3
.getDataLayerVirtualLan());
Assert.assertTrue(match.getDataLayerVirtualLanPriorityCodePoint() == match3
@Override
public void stopped(Component component) {
+ // do nothing
+ }
+
+ @Override
+ public void stopping(Component component) {
if (component == null) {
return;
}
{ Component.class }, {} }, new Object[][] { { component },
{} });
}
-
- @Override
- public void stopping(Component component) {
- // do nothing
- }
}
/**
package org.opendaylight.controller.sal.match;
import java.io.Serializable;
-
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
if (type != other.type) {
return false;
}
- return (type.equalValues(this.value, other.value) && type.equalMasks(this.mask, other.mask));
+ return type.equals(this.value, other.value, this.mask, other.mask);
}
}
package org.opendaylight.controller.sal.match;
-import java.net.Inet6Address;
+import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;
break;
case NW_SRC:
case NW_DST:
- result = prime * result + ((v == null)? 0 : v.hashCode());
- result = prime * result + ((m == null)? NetUtils.gethighestIP(v instanceof Inet6Address).hashCode() : m.hashCode());
+ // Hash code has to take into account only prefix address
+ InetAddress ip = (InetAddress) v;
+ int maskLen = (m == null) ? ((ip instanceof Inet4Address) ? 32 : 128) : NetUtils
+ .getSubnetMaskLength((InetAddress) m);
+ InetAddress prefix = NetUtils.getSubnetPrefix(ip, maskLen);
+ result = prime * result + ((v == null)? 0 : prefix.hashCode());
break;
default:
result = prime * result + ((v == null)? 0 : v.hashCode());
* For network address mask, network node may return full mask for
* flows the controller generated with a null mask object
*/
- byte maskBytes[] = null;
- if (a == null) {
- maskBytes = ((InetAddress) b).getAddress();
- } else if (b == null) {
- maskBytes = ((InetAddress) a).getAddress();
- }
- if (maskBytes != null) {
- return (NetUtils.getSubnetMaskLength(maskBytes) == 0);
+ if (a == null || b == null) {
+ InetAddress mask = (a == null) ? (InetAddress) b : (InetAddress) a;
+ int maxLength = (mask instanceof Inet4Address) ? 32 : 128;
+ return (NetUtils.getSubnetMaskLength(mask) == maxLength);
}
default:
if (a == null) {
return a.equals(b);
}
}
+
+ public boolean equals(Object value1, Object value2, Object mask1, Object mask2) {
+ switch (this) {
+ case NW_SRC:
+ case NW_DST:
+ // Equality to be checked against prefix addresses
+ InetAddress thisIP = (InetAddress) value1;
+ int thisMaskLen = (mask1 == null) ? ((thisIP instanceof Inet4Address) ? 32 : 128) : NetUtils
+ .getSubnetMaskLength((InetAddress) mask1);
+ InetAddress otherIP = (InetAddress) value2;
+ int otherMaskLen = (mask2 == null) ? ((otherIP instanceof Inet4Address) ? 32 : 128) : NetUtils
+ .getSubnetMaskLength((InetAddress) mask2);
+
+ return NetUtils.getSubnetPrefix(thisIP, thisMaskLen)
+ .equals(NetUtils.getSubnetPrefix(otherIP, otherMaskLen));
+ default:
+ return (this.equalValues(value1, value2) && this.equalMasks(mask1, mask2));
+ }
+ }
}
private static final String DIP = "DestinationIPAddress";
private static final String OPTIONS = "Options";
+ private static final int UNIT_SIZE_SHIFT = 2;
+ private static final int UNIT_SIZE = (1 << UNIT_SIZE_SHIFT);
+ private static final int MIN_HEADER_SIZE = 20;
+
public static final Map<Byte, Class<? extends Packet>> protocolClassMap;
static {
protocolClassMap = new HashMap<Byte, Class<? extends Packet>>();
public int getHeaderSize() {
int headerLen = this.getHeaderLen();
if (headerLen == 0) {
- headerLen = 20;
- }
-
- byte[] options = hdrFieldsMap.get(OPTIONS);
- if (options != null) {
- headerLen += options.length;
+ headerLen = MIN_HEADER_SIZE;
}
return headerLen * NetUtils.NumBitsInAByte;
public void setHeaderField(String headerField, byte[] readValue) {
if (headerField.equals(PROTOCOL)) {
payloadClass = protocolClassMap.get(readValue[0]);
+ } else if (headerField.equals(OPTIONS) &&
+ (readValue == null || readValue.length == 0)) {
+ hdrFieldsMap.remove(headerField);
+ return;
}
hdrFieldsMap.put(headerField, readValue);
}
* @return IPv4
*/
public IPv4 setOptions(byte[] options) {
- fieldValues.put(OPTIONS, options);
- byte newIHL = (byte) (5 + options.length);
+ byte newIHL = (byte)(MIN_HEADER_SIZE >>> UNIT_SIZE_SHIFT);
+ if (options == null || options.length == 0) {
+ fieldValues.remove(OPTIONS);
+ } else {
+ int len = options.length;
+ int rlen = (len + (UNIT_SIZE - 1)) & ~(UNIT_SIZE - 1);
+ if (rlen > len) {
+ // Padding is required.
+ byte[] newopt = new byte[rlen];
+ System.arraycopy(options, 0, newopt, 0, len);
+ options = newopt;
+ len = rlen;
+ }
+ fieldValues.put(OPTIONS, options);
+ newIHL += (len >>> UNIT_SIZE_SHIFT);
+ }
+
setHeaderLength(newIHL);
return this;
@Override
/**
* Gets the number of bits for the fieldname specified
- * If the fieldname has variable length like "Options", then this value is computed using the
- * options length and the header length
+ * If the fieldname has variable length like "Options", then this value is computed using the header length
* @param fieldname - String
* @return number of bits for fieldname - int
*/
public int getfieldnumBits(String fieldName) {
if (fieldName.equals(OPTIONS)) {
- byte[] options = getOptions();
- return ((options == null) ? 0 : (options.length - getHeaderLen()));
+ return (getHeaderLen() - MIN_HEADER_SIZE) * NetUtils.NumBitsInAByte;
}
return hdrFieldCoordMap.get(fieldName).getRight();
}
package org.opendaylight.controller.sal.utils;
+import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Constant holding the broadcast MAC address
*/
- public static byte[] BroadcastMACAddr = {-1, -1, -1, -1, -1, -1};
+ private static final byte[] BroadcastMACAddr = {-1, -1, -1, -1, -1, -1};
/**
* Converts a 4 bytes array into an integer number
}
/**
- * Returns the number of contiguous bits belonging to the subnet, that have
- * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will
- * give a subnet mask length of 8, while ff.00.00.00 will return a subnet
- * mask length of 24. If the passed prefixMask object is null, 0 is returned
+ * Returns the prefix size in bits of the specified subnet mask. Example:
+ * For the subnet mask ff.ff.ff.e0 it returns 25 while for ff.00.00.00 it
+ * returns 8. If the passed subnetMask array is null, 0 is returned.
*
- * @param prefixMask
- * the prefix mask as byte array
- * @return the length of the prefix network mask
+ * @param subnetMask
+ * the subnet mask as byte array
+ * @return the prefix length as number of bits
*/
- public static int getSubnetMaskLength(byte[] prefixMask) {
+ public static int getSubnetMaskLength(byte[] subnetMask) {
int maskLength = 0;
- if (prefixMask != null) {
- // Create bit mask
- int intMask = 0;
- int numBytes = prefixMask.length;
- for (int i = 0; i < numBytes; i++) {
- intMask |= (prefixMask[i] & 0xff) << (8 * (numBytes - 1 - i));
+ if (subnetMask != null && (subnetMask.length == 4 || subnetMask.length == 16)) {
+ int index = 0;
+ while (index < subnetMask.length && subnetMask[index] == (byte) 0xFF) {
+ maskLength += NetUtils.NumBitsInAByte;
+ index++;
}
-
- int bit = 1;
- while (((intMask & bit) == 0) && (maskLength <= (numBytes * 8))) {
- maskLength += 1;
- bit = bit << 1;
+ if (index != subnetMask.length) {
+ int bits = NetUtils.NumBitsInAByte - 1;
+ while (bits >= 0 && (subnetMask[index] & 1 << bits) != 0) {
+ bits--;
+ maskLength++;
+ }
}
}
return maskLength;
}
/**
- * Returns the number of contiguous bits belonging to the subnet, that have
- * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will
- * give a subnet mask length of 8, while ff.00.00.00 will return a subnet
- * mask length of 24 If the passed prefixMask object is null, 0 is returned
+ * Returns the prefix size in bits of the specified subnet mask. Example:
+ * For the subnet mask 255.255.255.128 it returns 25 while for 255.0.0.0 it
+ * returns 8. If the passed subnetMask object is null, 0 is returned
*
- * @param prefixMask
- * the prefix mask as InetAddress
- * @return the length of the prefix network mask
+ * @param subnetMask
+ * the subnet mask as InetAddress
+ * @return the prefix length as number of bits
*/
- public static int getSubnetMaskLength(InetAddress prefixMask) {
- return (prefixMask == null) ? 0 : NetUtils.getSubnetMaskLength(prefixMask.getAddress());
+ public static int getSubnetMaskLength(InetAddress subnetMask) {
+ return subnetMask == null ? 0 : NetUtils.getSubnetMaskLength(subnetMask.getAddress());
}
/**
return false;
}
- int testMaskLen = (testMask != null) ? NetUtils.getSubnetMaskLength(testMask.getAddress()) : 0;
- int filterMaskLen = (filterMask != null) ? NetUtils.getSubnetMaskLength(filterMask.getAddress()) : 0;
-
- int testPrefixLen = (testAddress instanceof Inet6Address) ? (128 - testMaskLen) : (32 - testMaskLen);
- int filterPrefixLen = (filterAddress instanceof Inet6Address) ? (128 - filterMaskLen) : (32 - filterMaskLen);
+ int testMaskLen = (testMask == null) ? ((testAddress instanceof Inet4Address) ? 32 : 128) : NetUtils
+ .getSubnetMaskLength(testMask);
+ int filterMaskLen = NetUtils.getSubnetMaskLength(filterMask);
// Mask length check. Test mask has to be more specific than filter one
- if (testPrefixLen < filterPrefixLen) {
+ if (testMaskLen < filterMaskLen) {
return true;
}
// Subnet Prefix on filter mask length must be the same
- InetAddress prefix1 = getSubnetPrefix(testAddress, filterPrefixLen);
- InetAddress prefix2 = getSubnetPrefix(filterAddress, filterPrefixLen);
+ InetAddress prefix1 = getSubnetPrefix(testAddress, filterMaskLen);
+ InetAddress prefix2 = getSubnetPrefix(filterAddress, filterMaskLen);
return (!prefix1.equals(prefix2));
}
}
}
}
- return new Status(StatusCode.SUCCESS, null);
+ return new Status(StatusCode.SUCCESS);
}
}
Assert.assertTrue(destinationAddress[3] == 110);
}
+ @Test
+ public void testOptions() throws Exception {
+ IPv4 ip = new IPv4();
+ Assert.assertEquals(20, ip.getHeaderLen());
+ Assert.assertEquals(160, ip.getHeaderSize());
+ Assert.assertEquals(0, ip.getfieldnumBits("Options"));
+
+ byte[][] options = {
+ new byte[] {
+ (byte)0x01,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ },
+ null,
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05, (byte)0x06,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05, (byte)0x06, (byte)0x07,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,
+ },
+ new byte[0],
+ };
+
+ byte[][] expected = {
+ new byte[] {
+ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ },
+ null,
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05, (byte)0x06, (byte)0x00, (byte)0x00,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x00,
+ },
+ new byte[] {
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+ (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,
+ },
+ null,
+ };
+
+ byte[] echo = {
+ (byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44,
+ (byte)0x55, (byte)0x66, (byte)0x77, (byte)0x88,
+ (byte)0x99, (byte)0xaa,
+ };
+ ICMP icmp = new ICMP();
+ icmp.setType((byte)8);
+ icmp.setCode((byte)0);
+ icmp.setIdentifier((short)0xabcd);
+ icmp.setSequenceNumber((short)7777);
+ icmp.setRawPayload(echo);
+
+ ip.setSourceAddress(InetAddress.getByName("192.168.10.20"));
+ ip.setDestinationAddress(InetAddress.getByName("192.168.30.40"));
+ ip.setProtocol(IPProtocols.ICMP.byteValue());
+
+ for (int i = 0; i < options.length; i++) {
+ byte[] opts = options[i];
+ byte[] exp = expected[i];
+
+ // Set IPv4 options.
+ int hlen = 20;
+ int optlen;
+ if (exp != null) {
+ optlen = exp.length;
+ hlen += optlen;
+ } else {
+ optlen = 0;
+ }
+ ip.setOptions(opts);
+ Assert.assertTrue(Arrays.equals(exp, ip.getOptions()));
+ Assert.assertEquals(hlen, ip.getHeaderLen());
+ Assert.assertEquals(hlen * 8, ip.getHeaderSize());
+ Assert.assertEquals(optlen * 8, ip.getfieldnumBits("Options"));
+
+ // Serialize/Deserialize test.
+ ip.setPayload(icmp);
+
+ byte[] raw = ip.serialize();
+ IPv4 newip = new IPv4();
+ newip.deserialize(raw, 0, raw.length * 8);
+ Assert.assertEquals(ip, newip);
+ Assert.assertEquals(icmp, newip.getPayload());
+ Assert.assertTrue(Arrays.equals(exp, newip.getOptions()));
+ }
+ }
+
@Test
public void testChecksum() {
byte header[] = { (byte) 0x45, 00, 00, (byte) 0x3c, (byte) 0x1c,
public void testGetSubnetLen() {
byte address[] = { (byte) 128, (byte) 0, (byte) 0, 0 };
- Assert.assertTrue(NetUtils.getSubnetMaskLength(address) == 31);
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address) == 1);
byte address1[] = { (byte) 255, 0, 0, 0 };
- Assert.assertTrue(NetUtils.getSubnetMaskLength(address1) == 24);
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address1) == 8);
byte address2[] = { (byte) 255, (byte) 255, (byte) 248, 0 };
- Assert.assertTrue(NetUtils.getSubnetMaskLength(address2) == 11);
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address2) == 21);
byte address4[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 254 };
- Assert.assertTrue(NetUtils.getSubnetMaskLength(address4) == 1);
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address4) == 31);
+
+ byte address5[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+ (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+ (byte) 255 };
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address5) == 128);
+
+ byte address6[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+ (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+ (byte) 254 };
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address6) == 127);
+
+ byte address7[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+ (byte) 255, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address7) == 64);
+
+ byte address8[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+ (byte) 254, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address8) == 63);
+
+ byte address9[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 128,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address9) == 49);
+
+ byte address10[] = { (byte) 128, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address10) == 1);
+
+ byte address11[] = { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+ Assert.assertTrue(NetUtils.getSubnetMaskLength(address11) == 0);
}
@Test
import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode;
import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule;
-import java.util.*;
import java.util.concurrent.Future;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.Future;
-import org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil;
import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
import org.opendaylight.controller.binding.generator.util.Types;
import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
if (genTOBuilder != null) {
returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
}
- } else if(typeDef instanceof BitsTypeDefinition) {
+ } else if (typeDef instanceof BitsTypeDefinition) {
GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
if (genTOBuilder != null) {
returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
- }
+ }
} else {
returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
}
return genTOBuilder;
}
-
- private GeneratedTOBuilder addEnclosedTOToTypeBuilder( TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder, String leafName) {
+ private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
+ String leafName) {
String className = parseToClassName(leafName);
GeneratedTOBuilder genTOBuilder = null;
if (typeDef instanceof UnionType) {
genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition(
- typeBuilder.getPackageName(), typeDef, className);
+ typeBuilder.getFullyQualifiedName(), typeDef, className);
} else if (typeDef instanceof BitsTypeDefinition) {
genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(
- typeBuilder.getPackageName(), typeDef, className);
+ typeBuilder.getFullyQualifiedName(), typeDef, className);
}
if (genTOBuilder != null) {
typeBuilder.addEnclosingTransferObject(genTOBuilder);
return genTOBuilder;
}
return null;
-
+
}
-
+
}
import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
import org.opendaylight.controller.yang.model.util.ExtendedType;
+
import org.opendaylight.controller.yang.model.util.StringType;
+import org.opendaylight.controller.yang.model.util.UnionType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.*;
final String basePackageName = moduleNamespaceToPackageName(module);
final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
+ final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
final Map<String, Type> typeMap = new HashMap<>();
genTypeDefsContextMap.put(moduleName, typeMap);
- if ((typeDefinitions != null) && (basePackageName != null)) {
- for (final TypeDefinition<?> typedef : typeDefinitions) {
+ if ((listTypeDefinitions != null) && (basePackageName != null)) {
+ for (final TypeDefinition<?> typedef : listTypeDefinitions) {
typedefToGeneratedType(basePackageName, moduleName, typedef);
}
- final List<ExtendedType> extUnions = UnionDependencySort.sort(typeDefinitions);
- for (final ExtendedType extUnionType : extUnions) {
- addUnionGeneratedTypeDefinition(basePackageName, extUnionType, null);
- }
}
}
}
if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
final String typedefName = typedef.getQName().getLocalName();
- final TypeDefinition<?> baseTypeDefinition = baseTypeDefForExtendedType(typedef);
- if (!(baseTypeDefinition instanceof LeafrefTypeDefinition)
- && !(baseTypeDefinition instanceof IdentityrefTypeDefinition)) {
- Type returnType;
- if (baseTypeDefinition instanceof EnumTypeDefinition) {
- final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDefinition;
+ final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
+ if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
+ && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
+ Type returnType = null;
+ if (innerTypeDefinition instanceof ExtendedType) {
+ ExtendedType extendedTypeDef = (ExtendedType) innerTypeDefinition;
+ returnType = resolveExtendedTypeFromTypeDef(extendedTypeDef, basePackageName, typedefName,
+ moduleName);
+ } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
+ final GeneratedTOBuilder genTOBuilder = addUnionGeneratedTypeDefinition(basePackageName, typedef,
+ typedefName);
+ returnType = genTOBuilder.toInstance();
+ } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
+ final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
- } else if (baseTypeDefinition instanceof BitsTypeDefinition) {
- final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) baseTypeDefinition;
- GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName, bitsTypeDefinition,
- typedefName);
+ } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
+ final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
+ final GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName,
+ bitsTypeDefinition, typedefName);
returnType = genTOBuilder.toInstance();
} else {
final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
- .javaTypeForSchemaDefinitionType(baseTypeDefinition);
+ .javaTypeForSchemaDefinitionType(innerTypeDefinition);
returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType);
}
genTOBuilder.addEqualsIdentity(genPropBuilder);
genTOBuilder.addHashIdentity(genPropBuilder);
genTOBuilder.addToStringProperty(genPropBuilder);
-
- if (typedef instanceof ExtendedType) {
- final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
- addStringRegExAsConstant(genTOBuilder, regExps);
+ if (javaType == BaseYangTypes.STRING_TYPE) {
+ if (typedef instanceof ExtendedType) {
+ final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
+ addStringRegExAsConstant(genTOBuilder, regExps);
+ }
}
-
return genTOBuilder.toInstance();
}
return null;
final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext, unionType);
if (unionTypeModule != null && unionTypeModule.getName() != null) {
final Map<String, Type> innerGenTOs = genTypeDefsContextMap.get(unionTypeModule.getName());
-
- final GeneratedTransferObject genTransferObject = (GeneratedTransferObject) innerGenTOs
- .get(typeName);
+ Type genTransferObject = null;
+ if (innerGenTOs != null) {
+ genTransferObject = innerGenTOs.get(typeName);
+ }
if (genTransferObject != null) {
updateUnionTypeAsProperty(unionGenTransObject, genTransferObject,
genTransferObject.getName());
}
}
+ private GeneratedTransferObject resolveExtendedTypeFromTypeDef(final ExtendedType extendedType,
+ final String basePackageName, final String typedefName, final String moduleName) {
+
+ if (extendedType == null) {
+ throw new IllegalArgumentException("Extended type cannot be NULL!");
+ }
+ if (basePackageName == null) {
+ throw new IllegalArgumentException("String with base package name cannot be NULL!");
+ }
+ if (typedefName == null) {
+ throw new IllegalArgumentException("String with type definition name cannot be NULL!");
+ }
+
+ final String typeDefName = parseToClassName(typedefName);
+ final String lowTypeDef = extendedType.getQName().getLocalName();
+ final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName);
+
+ final Map<String, Type> typeMap = genTypeDefsContextMap.get(moduleName);
+ if (typeMap != null) {
+ Type type = typeMap.get(lowTypeDef);
+ if (type instanceof GeneratedTransferObject) {
+ genTOBuilder.setExtendsType((GeneratedTransferObject) type);
+ }
+ }
+
+ return genTOBuilder.toInstance();
+ }
+
+ /**
+ * The method find out for each type definition how many immersion (depth)
+ * is necessary to get to the base type. Every type definition is inserted
+ * to the map which key is depth and value is list of type definitions with
+ * equal depth. In next step are lists from this map concatenated to one
+ * list in ascending order according to their depth. All type definitions
+ * are in the list behind all type definitions on which depends.
+ *
+ * @param unsortedTypeDefinitions
+ * represents list of type definitions
+ * @return list of type definitions sorted according their each other
+ * dependencies (type definitions which are depend on other type
+ * definitions are in list behind them).
+ */
+ private List<TypeDefinition<?>> sortTypeDefinitionAccordingDepth(
+ final Set<TypeDefinition<?>> unsortedTypeDefinitions) {
+ List<TypeDefinition<?>> sortedTypeDefinition = new ArrayList<>();
+
+ Map<Integer, List<TypeDefinition<?>>> typeDefinitionsDepths = new TreeMap<>();
+ for (TypeDefinition<?> unsortedTypeDefinition : unsortedTypeDefinitions) {
+ final int depth = getTypeDefinitionDepth(unsortedTypeDefinition);
+ List<TypeDefinition<?>> typeDefinitionsConcreteDepth = typeDefinitionsDepths.get(depth);
+ if (typeDefinitionsConcreteDepth == null) {
+ typeDefinitionsConcreteDepth = new ArrayList<TypeDefinition<?>>();
+ typeDefinitionsDepths.put(depth, typeDefinitionsConcreteDepth);
+ }
+ typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
+ }
+
+ Set<Integer> depths = typeDefinitionsDepths.keySet(); // keys are in
+ // ascending order
+ for (Integer depth : depths) {
+ sortedTypeDefinition.addAll(typeDefinitionsDepths.get(depth));
+ }
+
+ return sortedTypeDefinition;
+ }
+
+ /**
+ * The method return how many immersion is necessary to get from type
+ * definition to base type.
+ *
+ * @param typeDefinition
+ * is type definition for which is depth looked for.
+ * @return how many immersion is necessary to get from type definition to
+ * base type
+ */
+ private int getTypeDefinitionDepth(final TypeDefinition<?> typeDefinition) {
+ if (typeDefinition == null) {
+ throw new IllegalArgumentException("Type definition can't be null");
+ }
+ int depth = 1;
+ TypeDefinition<?> baseType = typeDefinition.getBaseType();
+
+ if (baseType instanceof ExtendedType) {
+ depth = depth + getTypeDefinitionDepth(typeDefinition.getBaseType());
+ } else if (baseType instanceof UnionType) {
+ List<TypeDefinition<?>> childTypeDefinitions = ((UnionType) baseType).getTypes();
+ int maxChildDepth = 0;
+ int childDepth = 1;
+ for (TypeDefinition<?> childTypeDefinition : childTypeDefinitions) {
+ childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition.getBaseType());
+ if (childDepth > maxChildDepth) {
+ maxChildDepth = childDepth;
+ }
+ }
+ return maxChildDepth;
+ }
+ return depth;
+ }
+
}
--- /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.generator.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
+import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
+import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
+import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
+
+public class BitAndUnionTOEnclosingTest {
+
+ private final static List<File> testModels = new ArrayList<File>();
+
+ @BeforeClass
+ public static void loadTestResources() {
+ final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/bit_and_union_in_leaf.yang")
+ .getPath());
+ testModels.add(listModelFile);
+ }
+
+ @Test
+ public void bitAndUnionEnclosingTest() {
+ final YangModelParser parser = new YangParserImpl();
+ final Set<Module> modules = parser.parseYangModels(testModels);
+ final SchemaContext context = parser.resolveSchemaContext(modules);
+
+ assertNotNull(context);
+ final BindingGenerator bindingGen = new BindingGeneratorImpl();
+ final List<Type> genTypes = bindingGen.generateTypes(context);
+
+ GeneratedType parentContainer = null;
+
+ for (Type type : genTypes) {
+ if ((type instanceof GeneratedType) && !(type instanceof GeneratedTransferObject)) {
+ GeneratedType genTO = (GeneratedType) type;
+ if (genTO.getName().equals("ParentContainer")) {
+ parentContainer = genTO;
+ break;
+ }
+ }
+ }
+
+ assertNotNull("Parent container object wasn't found.", parentContainer);
+
+ GeneratedTransferObject bitLeaf = null;
+ GeneratedTransferObject unionLeaf = null;
+ List<GeneratedType> enclosedTypes = parentContainer.getEnclosedTypes();
+ for (GeneratedType genType : enclosedTypes) {
+ if (genType instanceof GeneratedTransferObject) {
+ if (genType.getName().equals("BitLeaf")) {
+ bitLeaf = (GeneratedTransferObject) genType;
+ } else if (genType.getName().equals("UnionLeaf")) {
+ unionLeaf = (GeneratedTransferObject) genType;
+ }
+ }
+ }
+
+ assertNotNull("BitLeaf TO builder wasn't found.", bitLeaf);
+ assertNotNull("UnionLeaf TO builder wasn't found.", unionLeaf);
+
+ assertEquals("BitLeaf has incorrect package name.",
+ "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
+ bitLeaf.getPackageName());
+ assertEquals("UnionLeaf has incorrect package name.",
+ "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
+ bitLeaf.getPackageName());
+
+ List<GeneratedProperty> propertiesBitLeaf = bitLeaf.getProperties();
+ GeneratedProperty firstBitProperty = null;
+ GeneratedProperty secondBitProperty = null;
+ GeneratedProperty thirdBitProperty = null;
+ for (GeneratedProperty genProperty : propertiesBitLeaf) {
+ if (genProperty.getName().equals("firstBit")) {
+ firstBitProperty = genProperty;
+ } else if (genProperty.getName().equals("secondBit")) {
+ secondBitProperty = genProperty;
+ } else if (genProperty.getName().equals("thirdBit")) {
+ thirdBitProperty = genProperty;
+ }
+ }
+
+ assertNotNull("firstBit property wasn't found", firstBitProperty);
+ assertNotNull("secondBit property wasn't found", secondBitProperty);
+ assertNotNull("thirdBit property wasn't found", thirdBitProperty);
+
+ assertEquals("firstBit property has incorrect type", "Boolean", firstBitProperty.getReturnType().getName());
+ assertEquals("secondBit property has incorrect type", "Boolean", secondBitProperty.getReturnType().getName());
+ assertEquals("thirdBit property has incorrect type", "Boolean", thirdBitProperty.getReturnType().getName());
+
+ GeneratedProperty uint32Property = null;
+ GeneratedProperty stringProperty = null;
+ GeneratedProperty uint8Property = null;
+ List<GeneratedProperty> propertiesUnionLeaf = unionLeaf.getProperties();
+ for (GeneratedProperty genProperty : propertiesUnionLeaf) {
+ if (genProperty.getName().equals("int32")) {
+ uint32Property = genProperty;
+ } else if (genProperty.getName().equals("string")) {
+ stringProperty = genProperty;
+ } else if (genProperty.getName().equals("uint8")) {
+ uint8Property = genProperty;
+ }
+ }
+
+ assertNotNull("uint32 property wasn't found", uint32Property);
+ assertNotNull("string property wasn't found", stringProperty);
+ assertNotNull("uint8 property wasn't found", uint8Property);
+
+ assertEquals("uint32 property has incorrect type", "Integer", uint32Property.getReturnType().getName());
+ assertEquals("string property has incorrect type", "String", stringProperty.getReturnType().getName());
+ assertEquals("uint8 property has incorrect type", "Short", uint8Property.getReturnType().getName());
+
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.generator.impl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl;
+import org.opendaylight.controller.sal.binding.model.api.Constant;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
+import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;
+import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.yang.types.BaseYangTypes;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
+import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
+import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
+
+public class ExtendedTypedefTest {
+
+ private final static List<File> testModels = new ArrayList<File>();
+
+ @BeforeClass
+ public static void loadTestResources() {
+ final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/typedef_of_typedef.yang").getPath());
+ testModels.add(listModelFile);
+ }
+
+ @Test
+ public void constantGenerationTest() {
+ final YangModelParser parser = new YangParserImpl();
+ final Set<Module> modules = parser.parseYangModels(testModels);
+ final SchemaContext context = parser.resolveSchemaContext(modules);
+
+ assertNotNull(context);
+ final BindingGenerator bindingGen = new BindingGeneratorImpl();
+ final List<Type> genTypes = bindingGen.generateTypes(context);
+
+ GeneratedTransferObject simpleTypedef4 = null;
+ GeneratedTransferObject extendedTypedefUnion = null;
+ GeneratedTransferObject unionTypedef = null;
+ for (final Type type : genTypes) {
+ if (type instanceof GeneratedTransferObject) {
+ if (type.getName().equals("SimpleTypedef4")) {
+ simpleTypedef4 = (GeneratedTransferObject) type;
+ } else if (type.getName().equals("ExtendedTypedefUnion")) {
+ extendedTypedefUnion = (GeneratedTransferObject) type;
+ } else if (type.getName().equals("UnionTypedef")) {
+ unionTypedef = (GeneratedTransferObject) type;
+ }
+ }
+ }
+
+ // simple-typedef4
+ assertNotNull("SimpleTypedef4 not found", simpleTypedef4);
+ assertNotNull("ExtendedTypedefUnion not found", extendedTypedefUnion);
+ assertNotNull("UnionTypedef", unionTypedef);
+
+ List<GeneratedProperty> properties = simpleTypedef4.getProperties();
+ assertTrue("SimpleTypedef4 shouldn't have properties.", properties.isEmpty());
+
+ GeneratedTransferObject extendTO = simpleTypedef4.getExtends();
+ assertNotNull("SimpleTypedef4 should have extend.", extendTO);
+ assertEquals("Incorrect extension for SimpleTypedef4.", "SimpleTypedef3", extendTO.getName());
+ properties = extendTO.getProperties();
+ assertTrue("SimpleTypedef3 shouldn't have properties.", properties.isEmpty());
+
+ extendTO = extendTO.getExtends();
+ assertNotNull("SimpleTypedef3 should have extend.", extendTO);
+ assertEquals("Incorrect extension for SimpleTypedef3.", "SimpleTypedef2", extendTO.getName());
+ properties = extendTO.getProperties();
+ assertTrue("SimpleTypedef2 shouldn't have properties.", properties.isEmpty());
+
+ extendTO = extendTO.getExtends();
+ assertNotNull("SimpleTypedef2 should have extend.", extendTO);
+ assertEquals("SimpleTypedef2 should be extended with SimpleTypedef1.", "SimpleTypedef1", extendTO.getName());
+ properties = extendTO.getProperties();
+ assertEquals("Incorrect number of properties in class SimpleTypedef1.", 1, properties.size());
+
+ assertEquals("Incorrect property's name", "simpleTypedef1", properties.get(0).getName());
+ assertEquals("Property's incorrect type", BaseYangTypes.UINT8_TYPE, properties.get(0).getReturnType());
+
+ extendTO = extendTO.getExtends();
+ assertNull("SimpleTypedef1 shouldn't have extend.", extendTO);
+
+ // extended-typedef-union
+ assertNotNull("ExtendedTypedefUnion object not found", extendedTypedefUnion);
+ properties = extendedTypedefUnion.getProperties();
+ assertTrue("ExtendedTypedefUnion shouldn't have any property", properties.isEmpty());
+
+ extendTO = extendedTypedefUnion.getExtends();
+ assertEquals("Incorrect extension fo ExtendedTypedefUnion.", "UnionTypedef", extendTO.getName());
+ assertNull("UnionTypedef shouldn't be extended", extendTO.getExtends());
+ assertEquals("Incorrect number of properties for UnionTypedef.", 4, extendTO.getProperties().size());
+
+ GeneratedProperty simpleTypedef4Property = null;
+ GeneratedProperty simpleTypedef1Property = null;
+ GeneratedProperty byteTypeProperty = null;
+ GeneratedProperty typedefEnumFruitProperty = null;
+ for (GeneratedProperty genProperty : extendTO.getProperties()) {
+ if (genProperty.getName().equals("simpleTypedef1")) {
+ simpleTypedef1Property = genProperty;
+ } else if (genProperty.getName().equals("simpleTypedef4")) {
+ simpleTypedef4Property = genProperty;
+ } else if (genProperty.getName().equals("byteType")) {
+ byteTypeProperty = genProperty;
+ } else if (genProperty.getName().equals("typedefEnumFruit")) {
+ typedefEnumFruitProperty = genProperty;
+ }
+ }
+
+ assertNotNull("simpleTypedef4 property not found in UnionTypedef", simpleTypedef4Property);
+ assertNotNull("simpleTypedef1 property not found in UnionTypedef", simpleTypedef1Property);
+ assertNotNull("byteType property not found in UnionTypedef", byteTypeProperty);
+ assertNotNull("typedefEnumFruit property not found in UnionTypedef", typedefEnumFruitProperty);
+
+ assertEquals("Incorrect type for property simpleTypedef4.", "SimpleTypedef4", simpleTypedef4Property
+ .getReturnType().getName());
+ assertEquals("Incorrect type for property simpleTypedef1.", "SimpleTypedef1", simpleTypedef1Property
+ .getReturnType().getName());
+ assertEquals("Incorrect type for property byteType.", "ByteType", byteTypeProperty
+ .getReturnType().getName());
+ assertEquals("Incorrect type for property typedefEnumFruit.", "TypedefEnumFruit", typedefEnumFruitProperty
+ .getReturnType().getName());
+ }
+
+}
--- /dev/null
+module bit-and-union-in-leaf {
+
+ namespace "urn:bit:union:in:leaf";
+ prefix "sbd";
+
+ organization "OPEN DAYLIGHT";
+ contact "http://www.opendaylight.org/";
+
+ revision 2013-06-26 {
+
+ }
+
+ typedef union-typedef {
+ type union {
+ type string {
+ pattern "[a-g]";
+ };
+ type int16;
+ }
+ }
+
+ typedef union-typedef2 {
+ type union {
+ type string;
+ type int16;
+ }
+ }
+
+ container parent-container {
+ leaf bit-leaf {
+ type bits {
+ bit first-bit;
+ bit second-bit;
+ bit third-bit;
+ }
+ }
+
+ leaf union-leaf {
+ type union {
+ type int32;
+ type string {
+ pattern "[a-z]";
+ };
+ type string {
+ pattern "[0-9]*"
+ };
+ type string {
+ pattern "[a-d]*";
+ pattern "[0-5]*";
+ };
+ type uint8;
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+module typedef_typedef {
+
+ namespace "urn:typedef:typedef";
+ prefix "sbd";
+
+ organization "OPEN DAYLIGHT";
+ contact "http://www.opendaylight.org/";
+
+ revision 2013-07-09 {
+
+ }
+
+ typedef byte-type {
+ type bits {
+ bit first-bit {
+ position 10;
+ }
+ bit second-bit {
+ position 20;
+ }
+ }
+ }
+
+
+ typedef typedef-enum-fruit {
+ type enumeration {
+ enum "apple" {
+ value 1;
+ description "gold";
+ }
+ enum "pear" {
+ value 2;
+ }
+ }
+ }
+
+ typedef simple-typedef1 {
+ type uint8;
+ }
+
+ typedef simple-typedef2 {
+ type simple-typedef1;
+ }
+
+ typedef simple-typedef3 {
+ type simple-typedef2;
+ }
+
+ typedef simple-typedef4 {
+ type simple-typedef3;
+ }
+
+ typedef simple-typedef1-1 {
+ type uint16;
+ }
+
+
+ typedef union-typedef {
+ type union {
+ type simple-typedef1;
+ type simple-typedef4;
+ type byte-type;
+ type typedef-enum-fruit;
+ }
+ }
+
+ typedef extended-typedef-union {
+ type union-typedef;
+ }
+
+
+ typedef extended-typedef-simple {
+ type simple-typedef1;
+ }
+
+ typedef extended-typedef-enum {
+ type typedef-enum-fruit;
+ }
+}
\ No newline at end of file
}
writer.write(NL);
+ final boolean oneConstructor;
if (genTO.isUnionType()) {
- writer.write(GeneratorUtil.createConstructors(genTO, indent + TAB, imports, genTO.isAbstract()));
+ oneConstructor = false;
} else {
- writer.write(GeneratorUtil.createConstructor(genTO, indent + TAB, imports, genTO.isAbstract()) + NL);
+ oneConstructor = true;
}
+ writer.write(GeneratorUtil.createConstructor(genTO, indent + TAB, imports, genTO.isAbstract(),
+ oneConstructor));
writer.write(NL);
for (GeneratedProperty field : fields) {
import org.opendaylight.controller.binding.generator.util.TypeConstants;
import org.opendaylight.controller.sal.binding.model.api.*;
+import org.opendaylight.controller.binding.generator.util.Types;
import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair;
import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;
-import org.opendaylight.controller.binding.generator.util.Types;
public final class GeneratorUtil {
return builder.toString();
}
- public static String createConstructor(GeneratedTransferObject genTransferObject, final String indent,
- final Map<String, String> availableImports, boolean isIdentity) {
- StringBuilder builder = new StringBuilder();
+ public static String createConstructor(final GeneratedTransferObject genTransferObject, final String indent,
+ final Map<String, String> availableImports, final boolean isIdentity, final boolean oneConstructor) {
+ if (genTransferObject == null) {
+ throw new IllegalArgumentException("Generated transfer object can't be null");
+ }
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
+ if (availableImports == null) {
+ throw new IllegalArgumentException("Map of available imports can't be null");
+ }
+ GeneratedTransferObject genTOTopParent = getTopParrentTransportObject(genTransferObject);
+ final List<GeneratedProperty> ctorProperties = resolveReadOnlyPropertiesFromTO(genTransferObject
+ .getProperties());
+ final List<GeneratedProperty> ctorPropertiesAllParents = getPropertiesOfAllParents(genTransferObject
+ .getExtends());
final String currentPkg = genTransferObject.getPackageName();
- final List<GeneratedProperty> properties = genTransferObject.getProperties();
- final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
- if (properties != null) {
- for (final GeneratedProperty property : properties) {
- if (property.isReadOnly()) {
- ctorParams.add(property);
- }
+ final String className = genTransferObject.getName();
+
+ String constructorPart = "";
+ if (oneConstructor) {
+ if (genTOTopParent != genTransferObject && genTOTopParent.isUnionType()) {
+ constructorPart = createConstructorForEveryParentProperty(indent, isIdentity, ctorProperties,
+ ctorPropertiesAllParents, availableImports, currentPkg, className);
+
+ } else {
+ constructorPart = createOneConstructor(indent, isIdentity, ctorProperties, ctorPropertiesAllParents,
+ availableImports, currentPkg, className);
}
+
+ } else { // union won't be extended
+ constructorPart = createConstructorForEveryProperty(indent, isIdentity, ctorProperties,
+ ctorPropertiesAllParents, availableImports, currentPkg, className);
}
- builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity));
+ return constructorPart;
+ }
- final String parameterSeparator = COMMA + GAP;
- for (final GeneratedProperty ctorParam : ctorParams) {
- builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg));
- builder.append(parameterSeparator);
+ private static String createOneConstructor(final String indent, boolean isIdentity,
+ final List<GeneratedProperty> properties, final List<GeneratedProperty> propertiesAllParents,
+ final Map<String, String> availableImports, final String currentPkg, final String className) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
}
- if (!ctorParams.isEmpty()) {
- builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length());
+ if (properties == null) {
+ throw new IllegalArgumentException("List of generated properties can't be null");
}
- builder.append(createConstructorDeclarationFromRightParenthesis());
- builder.append(createConstructorSuperCalling(indent));
-
- for (final GeneratedProperty ctorParam : ctorParams) {
- builder.append(createClassAttributeInitialization(indent, ctorParam));
+ if (propertiesAllParents == null) {
+ throw new IllegalArgumentException(
+ "List of generated properties of all parent transport objects can't be null");
+ }
+ if (availableImports == null) {
+ throw new IllegalArgumentException("Map of available imports can't be null");
}
+ if (currentPkg == null) {
+ throw new IllegalArgumentException("String with current package can't be null");
+ }
+ if (className == null) {
+ throw new IllegalArgumentException("String with class name can't be null");
+ }
+
+ final StringBuilder builder = new StringBuilder();
+ List<GeneratedProperty> propertiesAll = new ArrayList<GeneratedProperty>(properties);
+ propertiesAll.addAll(propertiesAllParents);
+
+ builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity));
+ builder.append(createMethodPropertiesDeclaration(propertiesAll, availableImports, currentPkg, COMMA + GAP));
+ builder.append(createConstructorDeclarationFromRightParenthesis());
+ builder.append(createConstructorSuper(propertiesAllParents, indent));
+ builder.append(createClassPropertiesInitialization(propertiesAll, indent));
builder.append(createConstructorClosingPart(indent));
return builder.toString();
}
- public static String createConstructors(GeneratedTransferObject genTransferObject, final String indent,
- final Map<String, String> availableImports, boolean isIdentity) {
+ private static String createConstructorForEveryParentProperty(final String indent, final boolean isIdentity,
+ final List<GeneratedProperty> properties, final List<GeneratedProperty> propertiesAllParents,
+ final Map<String, String> availableImports, final String currentPkg, final String className) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
+ if (properties == null) {
+ throw new IllegalArgumentException("List of generated properties can't be null");
+ }
+ if (propertiesAllParents == null) {
+ throw new IllegalArgumentException(
+ "List of generated properties of all parent transport objects can't be null");
+ }
+ if (availableImports == null) {
+ throw new IllegalArgumentException("Map of available imports can't be null");
+ }
+ if (currentPkg == null) {
+ throw new IllegalArgumentException("String with current package can't be null");
+ }
+ if (className == null) {
+ throw new IllegalArgumentException("String with class name can't be null");
+ }
final StringBuilder builder = new StringBuilder();
+ GeneratedProperty parentProperty;
+ Iterator<GeneratedProperty> parentPropertyIterator = propertiesAllParents.iterator();
- final String currentPkg = genTransferObject.getPackageName();
- final List<GeneratedProperty> properties = genTransferObject.getProperties();
- final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
- if (properties != null) {
- for (final GeneratedProperty property : properties) {
- if (property.isReadOnly()) {
- ctorParams.add(property);
- }
+ do {
+ parentProperty = null;
+ if (parentPropertyIterator.hasNext()) {
+ parentProperty = parentPropertyIterator.next();
+ }
+
+ List<GeneratedProperty> propertiesAndParentProperties = new ArrayList<GeneratedProperty>();
+ if (parentProperty != null) {
+ propertiesAndParentProperties.add(parentProperty);
}
+ propertiesAndParentProperties.addAll(properties);
+
+ builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity));
+ builder.append(createMethodPropertiesDeclaration(propertiesAndParentProperties, availableImports,
+ currentPkg, COMMA + GAP));
+ builder.append(createConstructorDeclarationFromRightParenthesis());
+ builder.append(createConstructorSuper(parentProperty, indent));
+ builder.append(createClassPropertiesInitialization(properties, indent));
+ builder.append(createConstructorClosingPart(indent));
+ } while (parentPropertyIterator.hasNext());
+
+ return builder.toString();
+ }
+
+ private static String createConstructorForEveryProperty(final String indent, final boolean isIdentity,
+ final List<GeneratedProperty> properties, final List<GeneratedProperty> propertiesAllParents,
+ final Map<String, String> availableImports, final String currentPkg, final String className) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
+ if (properties == null) {
+ throw new IllegalArgumentException("List of generated properties can't be null");
+ }
+ if (propertiesAllParents == null) {
+ throw new IllegalArgumentException(
+ "List of generated properties of all parent transport objects can't be null");
+ }
+ if (availableImports == null) {
+ throw new IllegalArgumentException("Map of available imports can't be null");
+ }
+ if (currentPkg == null) {
+ throw new IllegalArgumentException("String with current package can't be null");
+ }
+ if (className == null) {
+ throw new IllegalArgumentException("String with class name can't be null");
}
- GeneratedProperty ctorParam;
- Iterator<GeneratedProperty> iteratorCtorParams = ctorParams.iterator();
+ final StringBuilder builder = new StringBuilder();
+
+ GeneratedProperty property;
+ Iterator<GeneratedProperty> propertyIterator = properties.iterator();
do {
- ctorParam = null;
- if (iteratorCtorParams.hasNext()) {
- ctorParam = iteratorCtorParams.next();
+ property = null;
+ if (propertyIterator.hasNext()) {
+ property = propertyIterator.next();
}
- builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity));
- if (ctorParam != null) {
- builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg));
+ List<GeneratedProperty> propertyAndTopParentProperties = new ArrayList<GeneratedProperty>();
+ if (property != null) {
+ propertyAndTopParentProperties.add(property);
}
+ propertyAndTopParentProperties.addAll(propertiesAllParents);
+
+ builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity));
+ builder.append(createMethodPropertiesDeclaration(propertyAndTopParentProperties, availableImports,
+ currentPkg, COMMA + GAP));
builder.append(createConstructorDeclarationFromRightParenthesis());
- builder.append(createConstructorSuperCalling(indent));
+ builder.append(createConstructorSuper(propertiesAllParents, indent));
+ builder.append(createClassPropertyInitialization(property, indent));
+ builder.append(createConstructorClosingPart(indent));
+ } while (propertyIterator.hasNext());
- if (ctorParam != null) {
- builder.append(createClassAttributeInitialization(indent, ctorParam));
+ return builder.toString();
+ }
+
+ /**
+ * The method selects from input list of properties only those which have
+ * read only attribute set to true.
+ *
+ * @param properties
+ * contains list of properties of generated transfer object
+ * @return subset of <code>properties</code> which have read only attribute
+ * set to true
+ */
+ private static List<GeneratedProperty> resolveReadOnlyPropertiesFromTO(List<GeneratedProperty> properties) {
+ List<GeneratedProperty> readOnlyProperties = new ArrayList<GeneratedProperty>();
+ if (properties != null) {
+ for (final GeneratedProperty property : properties) {
+ if (property.isReadOnly()) {
+ readOnlyProperties.add(property);
+ }
}
+ }
+ return readOnlyProperties;
+ }
- builder.append(createConstructorClosingPart(indent));
- } while (iteratorCtorParams.hasNext());
+ private static String createMethodPropertiesDeclaration(final List<GeneratedProperty> parameters,
+ final Map<String, String> availableImports, final String currentPkg, final String parameterSeparator) {
+ StringBuilder builder = new StringBuilder();
+ if (parameters == null) {
+ throw new IllegalArgumentException("List of generated properties can't be null");
+ }
+ if (availableImports == null) {
+ throw new IllegalArgumentException("Map of available imports can't be null");
+ }
+ if (currentPkg == null) {
+ throw new IllegalArgumentException("String with current package can't be null");
+ }
+ if (parameterSeparator == null) {
+ throw new IllegalArgumentException("String with separator of parameters can't be null");
+ }
+ for (final GeneratedProperty parameter : parameters) {
+ builder.append(createMethodPropertyDeclaration(parameter, availableImports, currentPkg));
+ builder.append(parameterSeparator);
+ }
+ if (!parameters.isEmpty()) {
+ builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length());
+ }
return builder.toString();
}
- private static String createConstructorDeclarationToLeftParenthesis(GeneratedTransferObject genTransferObject,
- final String indent, boolean isIdentity) {
+ private static String createConstructorDeclarationToLeftParenthesis(final String className, final String indent,
+ final boolean isIdentity) {
+ if (className == null) {
+ throw new IllegalArgumentException("String with class name can't be null");
+ }
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
final StringBuilder builder = new StringBuilder();
builder.append(indent);
builder.append(isIdentity ? PROTECTED : PUBLIC);
builder.append(GAP);
- builder.append(genTransferObject.getName());
+ builder.append(className);
builder.append(LB);
return builder.toString();
}
return builder.toString();
}
- private static String createConstructorSuperCalling(String indent) {
- final StringBuilder builder = new StringBuilder();
- builder.append(indent + TAB + "super();" + NL);
+ private static String createConstructorSuper(final List<GeneratedProperty> propertiesAllParents, final String indent) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
+ if (propertiesAllParents == null) {
+ throw new IllegalArgumentException("List of all parent's properties can't be null");
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append(indent + TAB + "super(");
+ String propertySeparator = COMMA + GAP;
+ for (GeneratedProperty superProperty : propertiesAllParents) {
+ builder.append(superProperty.getName());
+ builder.append(propertySeparator);
+ }
+ if (!propertiesAllParents.isEmpty()) {
+ builder = builder.delete(builder.length() - propertySeparator.length(), builder.length());
+ }
+
+ builder.append(");" + NL);
return builder.toString();
}
- private static String createConstructorClosingPart(String indent) {
+ private static String createConstructorSuper(final GeneratedProperty parentProperty, final String indent) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
+ if (parentProperty == null) {
+ throw new IllegalArgumentException("Parent property can't be null");
+ }
+ StringBuilder builder = new StringBuilder();
+ if (parentProperty != null) {
+ builder.append(indent + TAB + "super(");
+ builder.append(parentProperty.getName());
+ builder.append(");" + NL);
+ }
+ return builder.toString();
+ }
+
+ private static String createConstructorClosingPart(final String indent) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
final StringBuilder builder = new StringBuilder();
builder.append(indent);
builder.append(RCB);
return builder.toString();
}
- private static String createClassAttributeInitialization(String indent, GeneratedProperty methodParameter) {
+ private static String createClassPropertiesInitialization(final List<GeneratedProperty> properties,
+ final String indent) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
+ if (properties == null) {
+ throw new IllegalArgumentException("List of generated class properties can't be null");
+ }
+ final StringBuilder builder = new StringBuilder();
+ for (final GeneratedProperty property : properties) {
+ createClassPropertyInitialization(property, indent);
+ }
+ return builder.toString();
+ }
+
+ private static String createClassPropertyInitialization(final GeneratedProperty property, final String indent) {
+ if (indent == null) {
+ throw new IllegalArgumentException("String with indent can't be null");
+ }
+ if (property == null) {
+ throw new IllegalArgumentException("List of generated class properties can't be null");
+ }
final StringBuilder builder = new StringBuilder();
builder.append(indent);
builder.append(TAB);
builder.append("this.");
- builder.append(methodParameter.getName());
+ builder.append(property.getName());
builder.append(" = ");
- builder.append(methodParameter.getName());
+ builder.append(property.getName());
builder.append(SC);
builder.append(NL);
return builder.toString();
}
- private static String createMethodParamDeclaration(GeneratedProperty methodParameter,
- final Map<String, String> availableImports, String currentPkg) {
+ private static String createMethodPropertyDeclaration(final GeneratedProperty property,
+ final Map<String, String> availableImports, final String currentPkg) {
+ if (property == null) {
+ throw new IllegalArgumentException("Generated property can't be null");
+ }
+ if (availableImports == null) {
+ throw new IllegalArgumentException("Map of available imports can't be null");
+ }
+ if (currentPkg == null) {
+ throw new IllegalArgumentException("String with current package can't be null");
+ }
final StringBuilder builder = new StringBuilder();
- builder.append(getExplicitType(methodParameter.getReturnType(), availableImports, currentPkg));
+ builder.append(getExplicitType(property.getReturnType(), availableImports, currentPkg));
builder.append(GAP);
- builder.append(methodParameter.getName());
+ builder.append(property.getName());
return builder.toString();
}
return false;
}
+ /**
+ * The method returns reference to highest (top parent) Generated Transfer
+ * Object.
+ *
+ * @param childTransportObject
+ * is generated transfer object which can be extended by other
+ * generated transfer object
+ * @return in first case that <code>childTransportObject</code> isn't
+ * extended then <code>childTransportObject</code> is returned. In
+ * second case the method is recursive called until first case.
+ */
+ private static GeneratedTransferObject getTopParrentTransportObject(GeneratedTransferObject childTransportObject) {
+ if (childTransportObject == null) {
+ throw new IllegalArgumentException("Parameter childTransportObject can't be null.");
+ }
+ if (childTransportObject.getExtends() == null) {
+ return childTransportObject;
+ } else {
+ return getTopParrentTransportObject(childTransportObject.getExtends());
+ }
+ }
+
+ /**
+ * The method returns the list of the properties of all extending generated
+ * transfer object from <code>genTO</code> to highest parent generated
+ * transfer object
+ *
+ * @param genTO
+ * @return the list of all properties from actual to highest parent
+ * generated transfer object. In case when extension exists the
+ * method is recursive called.
+ */
+ private static List<GeneratedProperty> getPropertiesOfAllParents(GeneratedTransferObject genTO) {
+ List<GeneratedProperty> propertiesOfAllParents = new ArrayList<GeneratedProperty>();
+ if (genTO != null) {
+ final List<GeneratedProperty> allPropertiesOfTO = genTO.getProperties();
+ List<GeneratedProperty> readOnlyPropertiesOfTO = resolveReadOnlyPropertiesFromTO(allPropertiesOfTO);
+ propertiesOfAllParents.addAll(readOnlyPropertiesOfTO);
+ if (genTO.getExtends() != null) {
+ propertiesOfAllParents.addAll(getPropertiesOfAllParents(genTO.getExtends()));
+ }
+ }
+ return propertiesOfAllParents;
+ }
+
public static String createStaticInicializationBlock(GeneratedTransferObject genTransferObject, String indent) {
final StringBuilder builder = new StringBuilder();
-<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">\r
- <modelVersion>4.0.0</modelVersion>\r
- <parent>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>binding-generator</artifactId>\r
- <version>0.5.4-SNAPSHOT</version>\r
- </parent>\r
- <artifactId>binding-model-api</artifactId>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+ <parent>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>binding-generator</artifactId>\r
+ <version>0.5.4-SNAPSHOT</version>\r
+ </parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <artifactId>binding-model-api</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>${project.artifactId}</description>\r
+\r
</project>\r
-<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>
+<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">
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-prototype</artifactId>
<version>0.5-SNAPSHOT</version>
</parent>
- <version>0.5.4-SNAPSHOT</version>
+ <modelVersion>4.0.0</modelVersion>
+ <version>0.5.4-SNAPSHOT</version>
<artifactId>binding-generator</artifactId>
<packaging>pom</packaging>
- <name>binding-generator</name>
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<target>1.7</target>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.8.1</version>
- <configuration>
- <stylesheet>maven</stylesheet>
- </configuration>
- <executions>
- <execution>
- <goals>
- <goal>aggregate</goal>
- </goals>
- <phase>site</phase>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
+
</project>
--- /dev/null
+module typedef_typedef {
+
+ namespace "urn:typedef:typedef";
+ prefix "sbd";
+
+ organization "OPEN DAYLIGHT";
+ contact "http://www.opendaylight.org/";
+
+ revision 2013-07-09 {
+
+ }
+
+ typedef byte-type {
+ type bits {
+ bit first-bit {
+ position 10;
+ }
+ bit second-bit {
+ position 20;
+ }
+ }
+ }
+
+
+ typedef typedef-enum-fruit {
+ type enumeration {
+ enum "apple" {
+ value 1;
+ description "gold";
+ }
+ enum "pear" {
+ value 2;
+ }
+ }
+ }
+
+ typedef simple-typedef1 {
+ type uint8;
+ }
+
+ typedef simple-typedef2 {
+ type simple-typedef1;
+ }
+
+ typedef simple-typedef3 {
+ type simple-typedef2;
+ }
+
+ typedef simple-typedef4 {
+ type simple-typedef3;
+ }
+
+ typedef simple-typedef1-1 {
+ type uint16;
+ }
+
+
+ typedef union-typedef {
+ type union {
+ type simple-typedef1;
+ type simple-typedef4;
+ type byte-type;
+ type typedef-enum-fruit;
+ }
+ }
+
+ typedef extended-typedef-union {
+ type union-typedef;
+ }
+
+
+ typedef extended-typedef-simple {
+ type simple-typedef1;
+ }
+
+ typedef extended-typedef-enum {
+ type typedef-enum-fruit;
+ }
+}
\ No newline at end of file
+++ /dev/null
-module sample {
- yang-version 1;
- namespace "sample";
- prefix "s";
-
- revision 2013-06-13 {
- description "Initial demo";
- }
-
-
-
- // Simple Type definition
-
- typedef foo-name {
- type string;
- }
-
- // Storage / data structure
-
- container topologies {
- list topology {
- leaf foo-name {
- type string;
- }
- }
- }
-
-
- // Notification / Event
-
- notification packet-in {
- leaf node {
- type string;
- }
- leaf port {
- type uint16;
- }
- leaf content {
- type binary;
- }
- }
-
- // RPC
-
- rpc packet-out {
- input {
- leaf node {
- type string;
- }
- leaf port {
- type uint16;
- }
- leaf content {
- type binary;
- }
- }
- output {
-
- }
- }
-
-}
\ No newline at end of file
--- /dev/null
+module toaster {
+
+ yang-version 1;
+
+ namespace
+ "http://netconfcentral.org/ns/toaster";
+
+ prefix toast;
+
+ organization "Netconf Central";
+
+ contact
+ "Andy Bierman <andy@netconfcentral.org>";
+
+ description
+ "YANG version of the TOASTER-MIB.";
+
+ revision "2009-11-20" {
+ description
+ "Toaster module in progress.";
+ }
+
+
+ identity toast-type {
+ description
+ "Base for all bread types supported by the toaster.
+ New bread types not listed here nay be added in the
+ future.";
+ }
+
+ identity white-bread {
+ base toast:toast-type;
+ description "White bread.";
+ }
+
+ identity wheat-bread {
+ base toast-type;
+ description "Wheat bread.";
+ }
+
+ identity wonder-bread {
+ base toast-type;
+ description "Wonder bread.";
+ }
+
+ identity frozen-waffle {
+ base toast-type;
+ description "Frozen waffle.";
+ }
+
+ identity frozen-bagel {
+ base toast-type;
+ description "Frozen bagel.";
+ }
+
+ identity hash-brown {
+ base toast-type;
+ description "Hash browned potatos.";
+ }
+
+ typedef DisplayString {
+ type string;
+ description
+ "YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
+ reference
+ "RFC 2579, section 2.";
+
+ }
+
+ container toaster {
+ presence
+ "Indicates the toaster service is available";
+ description
+ "Top-level container for all toaster database objects.";
+ leaf toasterManufacturer {
+ type DisplayString;
+ config false;
+ mandatory true;
+ description
+ "The name of the toaster's manufacturer. For instance,
+ Microsoft Toaster.";
+ }
+
+ leaf toasterModelNumber {
+ type DisplayString;
+ config false;
+ mandatory true;
+ description
+ "The name of the toaster's model. For instance,
+ Radiant Automatic.";
+ }
+
+ leaf toasterStatus {
+ type enumeration {
+ enum "up" {
+ value 1;
+ description
+ "The toaster knob position is up.
+ No toast is being made now.";
+ }
+ enum "down" {
+ value 2;
+ description
+ "The toaster knob position is down.
+ Toast is being made now.";
+ }
+ }
+ config false;
+ mandatory true;
+ description
+ "This variable indicates the current state of
+ the toaster.";
+ }
+ } // container toaster
+
+ rpc make-toast {
+ description
+ "Make some toast.
+ The toastDone notification will be sent when
+ the toast is finished.
+ An 'in-use' error will be returned if toast
+ is already being made.
+ A 'resource-denied' error will be returned
+ if the toaster service is disabled.";
+ input {
+ leaf toasterDoneness {
+ type uint32 {
+ range "1 .. 10";
+ }
+ default '5';
+ description
+ "This variable controls how well-done is the
+ ensuing toast. It should be on a scale of 1 to 10.
+ Toast made at 10 generally is considered unfit
+ for human consumption; toast made at 1 is warmed
+ lightly.";
+ }
+
+ leaf toasterToastType {
+ type identityref {
+ base toast:toast-type;
+ }
+ default 'wheat-bread';
+ description
+ "This variable informs the toaster of the type of
+ material that is being toasted. The toaster
+ uses this information, combined with
+ toasterDoneness, to compute for how
+ long the material must be toasted to achieve
+ the required doneness.";
+ }
+ }
+ } // rpc make-toast
+
+ rpc cancel-toast {
+ description
+ "Stop making toast, if any is being made.
+ A 'resource-denied' error will be returned
+ if the toaster service is disabled.";
+ } // rpc cancel-toast
+
+ notification toastDone {
+ description
+ "Indicates that the toast in progress has completed.";
+ leaf toastStatus {
+ type enumeration {
+ enum "done" {
+ value 0;
+ description "The toast is done.";
+ }
+ enum "cancelled" {
+ value 1;
+ description
+ "The toast was cancelled.";
+ }
+ enum "error" {
+ value 2;
+ description
+ "The toaster service was disabled or
+ the toaster is broken.";
+ }
+ }
+ description
+ "Indicates the final toast status";
+ }
+ } // notification toastDone
+ } // module toaster
--- /dev/null
+<project name="${project.name}">
+
+ <skin>
+ <groupId>org.apache.maven.skins</groupId>
+ <artifactId>maven-fluido-skin</artifactId>
+ <version>1.3.0</version>
+ </skin>
+
+ <body>
+ <menu ref="parent"/>
+ <menu ref="modules"/>
+ <menu ref="reports"/>
+ </body>
+
+</project>
+
<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>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
<parent>
<artifactId>yang-prototype</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5-SNAPSHOT</version>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>concepts-lang</artifactId>
<packaging>jar</packaging>
-</project>
\ No newline at end of file
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
+
+</project>
--- /dev/null
+<project name="${project.name}">
+
+ <skin>
+ <groupId>org.apache.maven.skins</groupId>
+ <artifactId>maven-fluido-skin</artifactId>
+ <version>1.3.0</version>
+ </skin>
+
+ <body>
+ <menu ref="parent"/>
+ <menu ref="modules"/>
+ <menu ref="reports"/>
+ </body>
+
+</project>
+
<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>
<artifactId>model-ietf</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5-SNAPSHOT</version>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>ietf-inet-types</artifactId>
<version>2010.09.24-SNAPSHOT</version>
-</project>
\ No newline at end of file
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
+
+</project>
<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>
<artifactId>model-ietf</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5-SNAPSHOT</version>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>ietf-yang-types</artifactId>
<version>2010.09.24-SNAPSHOT</version>
-</project>
\ No newline at end of file
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
+
+</project>
<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>
<artifactId>model-parent</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5-SNAPSHOT</version>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>model-ietf</artifactId>
<packaging>pom</packaging>
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
+
<modules>
- <module>ietf-inet-types</module>
- <module>ietf-yang-types</module>
+ <module>ietf-inet-types</module>
+ <module>ietf-yang-types</module>
</modules>
-</project>
\ No newline at end of file
+
+</project>
<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>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
<parent>
<artifactId>yang-prototype</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5-SNAPSHOT</version>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>model-parent</artifactId>
<packaging>pom</packaging>
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
+
<modules>
<module>ietf</module>
<module>model-topology</module>
<module>model-openflow</module>
- <!--module>model-topology-bgp</module-->
+ <!-- <module>model-topology-bgp</module> -->
</modules>
<build>
</plugins>
<pluginManagement>
<plugins>
- <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <!--This plugin's configuration is used to store Eclipse
+ m2e settings only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
</plugins>
</pluginManagement>
</build>
+
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<version>0.5.4-SNAPSHOT</version>
</dependency>
</dependencies>
+
</project>
--- /dev/null
+<project name="${project.name}">
+
+ <skin>
+ <groupId>org.apache.maven.skins</groupId>
+ <artifactId>maven-fluido-skin</artifactId>
+ <version>1.3.0</version>
+ </skin>
+
+ <body>
+ <menu ref="parent"/>
+ <menu ref="modules"/>
+ <menu ref="reports"/>
+ </body>
+
+</project>
+
<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>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-prototype</artifactId>
<version>0.5-SNAPSHOT</version>
<packaging>pom</packaging>
+ <name>${project.artifactId}</name>
+ <description>
+ YANG Tools is a infrastructure project aiming to develop necessary tooling and libraries providing support of
+ NETCONF and YANG for Java (JVM-language based) projects and applications, such as Model Driven SAL for
+ Controller (which uses YANG as it's modeling language) and Netconf / OFConfig plugins.
+ </description>
+
+ <developers>
+ <developer>
+ <id>ttkacik</id>
+ <name>Tony Tkacik</name>
+ <email>ttkacik@cisco.com</email>
+ <organization>OpenDaylight</organization>
+ </developer>
+ <developer>
+ <id>rovarga</id>
+ <name>Robert Varga</name>
+ <email>rovarga@cisco.com</email>
+ <organization>OpenDaylight</organization>
+ </developer>
+ <developer>
+ <id>lsedlak</id>
+ <name>Lukas Sedlak</name>
+ <email>lsedlak@cisco.com</email>
+ <organization>OpenDaylight</organization>
+ </developer>
+ <developer>
+ <id>mvitez</id>
+ <name>Martin Vitez</name>
+ <email>mvitez@cisco.com</email>
+ <organization>OpenDaylight</organization>
+ </developer>
+ <developer>
+ <id>jmedved</id>
+ <name>Jan Medved</name>
+ <email>jmedved@cisco.com</email>
+ <organization>OpenDaylight</organization>
+ </developer>
+ <developer>
+ <id>jgloncak</id>
+ <name>Jozef Gloncak</name>
+ <email>jgloncak@cisco.com</email>
+ <organization>OpenDaylight</organization>
+ </developer>
+ <developer>
+ <id>mirehak</id>
+ <name>Michal Rehak</name>
+ <email>mirehak@cisco.com</email>
+ <organization>OpenDaylight</organization>
+ </developer>
+ </developers>
+
<modules>
<module>concepts-lang</module>
<module>yang</module>
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
<sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
<siteplugin>3.2</siteplugin>
+ <defaultStylesheet>${project.basedir}/src/site/resources/stylesheet.css</defaultStylesheet>
<projectinfo>2.6</projectinfo>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler.version>2.3.2</compiler.version>
<name>ops4j-releases</name>
<url>${nexusproxy}/repositories/ops4j-releases/</url>
</repository>
- <!-- Third Packages hosted in local maven because not available in other
- places -->
+ <!-- Third Packages hosted in local maven because not available in
+ other places -->
<repository>
<id>thirdparty</id>
<name>thirdparty</name>
<id>opendaylight-snapshot</id>
<url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
</snapshotRepository>
- <!-- Site deployment -->
- <!-- site>
- <id>website</id>
- <url>${sitedeploy}</url>
- </site -->
+ <site>
+ <id>${project.artifactId}-site</id>
+ <url>./</url>
+ </site>
</distributionManagement>
-
<dependencyManagement>
<dependencies>
<dependency>
</dependency>
</dependencies>
</dependencyManagement>
+
<build>
<plugins>
<plugin>
<target>1.7</target>
</configuration>
</plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>deploy</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <!-- explicitly define maven-deploy-plugin after other to
+ force exec order -->
+ <artifactId>maven-deploy-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>deploy</id>
+ <phase>deploy</phase>
+ <goals>
+ <goal>deploy</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>2.8.1</version>
<configuration>
- <stylesheet>maven</stylesheet>
+ <stylesheetfile>${defaultStylesheet}</stylesheetfile>
+ <excludePackageNames>
+ *.opendaylight.controller.antlrv4.code.gen
+ </excludePackageNames>
</configuration>
<executions>
<execution>
+ <id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>site</phase>
- </execution>
- <execution>
- <id>attach-javadocs</id>
- <phase>deploy</phase>
- <goals><goal>jar</goal></goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-source-plugin</artifactId>
- <executions>
+ </execution>
<execution>
- <id>attach-sources</id>
+ <id>attach-javadocs</id>
<phase>deploy</phase>
- <goals><goal>jar-no-fork</goal></goals>
+ <goals>
+ <goal>jar</goal>
+ </goals>
</execution>
- </executions>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <inherited>false</inherited>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.doxia</groupId>
+ <artifactId>doxia-module-markdown</artifactId>
+ <version>1.3</version>
+ </dependency>
+ </dependencies>
+ <configuration>
+ <siteDirectory>${project.basedir}/src/site</siteDirectory>
+ <inputEncoding>UTF-8</inputEncoding>
+ <outputEncoding>UTF-8</outputEncoding>
+ </configuration>
</plugin>
- <plugin>
- <!-- explicitly define maven-deploy-plugin after other to force exec order -->
- <artifactId>maven-deploy-plugin</artifactId>
- <executions>
- <execution>
- <id>deploy</id>
- <phase>deploy</phase>
- <goals><goal>deploy</goal></goals>
- </execution>
- </executions>
- </plugin>
</plugins>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.7</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.15</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.doxia</groupId>
+ <artifactId>doxia-module-markdown</artifactId>
+ <version>1.3</version>
+ </dependency>
+ </dependencies>
+ <configuration>
+ <siteDirectory>${project.parent.basedir}/src/site</siteDirectory>
+ <inputEncoding>UTF-8</inputEncoding>
+ <outputEncoding>UTF-8</outputEncoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ <configuration>
+ <stylesheetfile>${defaultStylesheet}</stylesheetfile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>aggregate</id>
+ <goals>
+ <goal>aggregate</goal>
+ </goals>
+ <phase>site</phase>
+ </execution>
+ <execution>
+ <id>attach-javadocs</id>
+ <phase>deploy</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
</build>
+
<reporting>
<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>javadoc</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
</plugin>
</plugins>
</reporting>
+
<profiles>
<profile>
<id>viewbuild</id>
--- /dev/null
+YANG tools
+====================
+
+Project documentation
+---------------------
+
+### Description
+
+YANG Tools is a infrastructure project aiming to develop necessary tooling and libraries providing support of NETCONF and YANG for Java (JVM-language based) projects and applications, such as Model Driven SAL for Controller (which uses YANG as it's modeling language) and Netconf / OFConfig plugins.
+
+### Scope
+
+The scope of YANG Tools includes:
+
+* Parser of YANG files
+* Java meta-model for YANG
+* Java binding for YANG
+* Maven plugin for processing YANG files
+* Infrastructure for code generators based on YANG
+* Validation of instance data (XML) based on YANG to RelaxNG mapping - RFC6110
+* Proof-of-concept, research and support for new YANG extensions, which are meant to be reused by other projects.
+* IDE related tools to assist in writing, using and developing YANG models
+* Libraries and supporting functionality for YANG API (REST APIs defined by the YANG model).
+
--- /dev/null
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:Arial, Helvetica, sans-serif;
+ font-size:76%;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4c6b87;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4c6b87;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-size:1.3em;
+}
+h1 {
+ font-size:1.8em;
+}
+h2 {
+ font-size:1.5em;
+}
+h3 {
+ font-size:1.4em;
+}
+h4 {
+ font-size:1.3em;
+}
+h5 {
+ font-size:1.2em;
+}
+h6 {
+ font-size:1.1em;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-size:1.2em;
+}
+dt code {
+ font-size:1.2em;
+}
+table tr td dt code {
+ font-size:1.2em;
+ vertical-align:top;
+}
+sup {
+ font-size:.6em;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:.8em;
+ z-index:200;
+ margin-top:-7px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ background-image:url(resources/titlebar.gif);
+ background-position:left top;
+ background-repeat:no-repeat;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:1em;
+ margin:0;
+}
+.topNav {
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+}
+.bottomNav {
+ margin-top:10px;
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+}
+.subNav {
+ background-color:#dee3e9;
+ border-bottom:1px solid #9eadc0;
+ float:left;
+ width:100%;
+ overflow:hidden;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding:3px 6px;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+ font-size:90%;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+.navBarCell1Rev {
+ background-image:url(resources/tab.gif);
+ background-color:#a88834;
+ color:#FFFFFF;
+ margin: auto 5px;
+ border:1px solid #c9aa44;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader span{
+ margin-right:15px;
+}
+.indexHeader h1 {
+ font-size:1.3em;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 25px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:1.2em;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ margin:0 0 6px -8px;
+ padding:2px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ margin:0 0 6px -8px;
+ padding:2px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:1.0em;
+}
+.indexContainer h2 {
+ font-size:1.1em;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:1.1em;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:10px 0 10px 20px;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:25px;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #9eadc0;
+ background-color:#f9f9f9;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:1px solid #9eadc0;
+ border-top:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+ border-bottom:1px solid #9eadc0;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.contentContainer table, .classUseContainer table, .constantValuesContainer table {
+ border-bottom:1px solid #9eadc0;
+ width:100%;
+}
+.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
+ width:100%;
+}
+.contentContainer .description table, .contentContainer .details table {
+ border-bottom:none;
+}
+.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
+ vertical-align:top;
+ padding-right:20px;
+}
+.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
+.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
+.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
+.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
+ padding-right:3px;
+}
+.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#FFFFFF;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ margin:0px;
+ white-space:pre;
+}
+caption a:link, caption a:hover, caption a:active, caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
+ white-space:nowrap;
+ padding-top:8px;
+ padding-left:8px;
+ display:block;
+ float:left;
+ background-image:url(resources/titlebar.gif);
+ height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:8px;
+ padding-left:8px;
+ display:block;
+ float:left;
+ background-image:url(resources/activetitlebar.gif);
+ height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:8px;
+ padding-left:8px;
+ display:block;
+ float:left;
+ background-image:url(resources/titlebar.gif);
+ height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.tableTab, .contentContainer ul.blockList li.blockList caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
+.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
+ width:10px;
+ background-image:url(resources/titlebar_end.gif);
+ background-repeat:no-repeat;
+ background-position:top right;
+ position:relative;
+ float:left;
+}
+.contentContainer ul.blockList li.blockList .activeTableTab .tabEnd {
+ width:10px;
+ margin-right:5px;
+ background-image:url(resources/activetitlebar_end.gif);
+ background-repeat:no-repeat;
+ background-position:top right;
+ position:relative;
+ float:left;
+}
+.contentContainer ul.blockList li.blockList .tableTab .tabEnd {
+ width:10px;
+ margin-right:5px;
+ background-image:url(resources/titlebar_end.gif);
+ background-repeat:no-repeat;
+ background-position:top right;
+ position:relative;
+ float:left;
+}
+ul.blockList ul.blockList li.blockList table {
+ margin:0 0 12px 0px;
+ width:100%;
+}
+.tableSubHeadingColor {
+ background-color: #EEEEFF;
+}
+.altColor {
+ background-color:#eeeeef;
+}
+.rowColor {
+ background-color:#ffffff;
+}
+.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
+ text-align:left;
+ padding:3px 3px 3px 7px;
+}
+th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
+ background:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ text-align:left;
+ padding:3px 3px 3px 7px;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+td.colFirst, th.colFirst {
+ border-left:1px solid #9eadc0;
+ white-space:nowrap;
+}
+td.colLast, th.colLast {
+ border-right:1px solid #9eadc0;
+}
+td.colOne, th.colOne {
+ border-right:1px solid #9eadc0;
+ border-left:1px solid #9eadc0;
+}
+table.overviewSummary {
+ padding:0px;
+ margin-left:0px;
+}
+table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
+table.overviewSummary td.colOne, table.overviewSummary th.colOne {
+ width:25%;
+ vertical-align:middle;
+}
+table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
+ width:25%;
+ vertical-align:middle;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:.9em;
+}
+.block {
+ display:block;
+ margin:3px 0 0 0;
+}
+.strong {
+ font-weight:bold;
+}
+
--- /dev/null
+<project name="${project.name}">
+
+ <skin>
+ <groupId>org.apache.maven.skins</groupId>
+ <artifactId>maven-fluido-skin</artifactId>
+ <version>1.3.0</version>
+ </skin>
+
+ <body>
+ <menu ref="parent"/>
+ <menu ref="modules"/>
+ <menu ref="reports"/>
+ <menu name="Overview">
+ <item name="Readme" href="readme.html" />
+ </menu>
+ </body>
+
+</project>
<artifactId>yang</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5.4-SNAPSHOT</version>
- <relativePath>../../yang/pom.xml</relativePath>
</parent>
<artifactId>yang-maven-plugin-it</artifactId>
<artifactId>yang</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5.4-SNAPSHOT</version>
- <relativePath>../../yang/pom.xml</relativePath>
</parent>
<artifactId>yang-maven-plugin</artifactId>
<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>
<artifactId>yang</artifactId>
<groupId>org.opendaylight.controller</groupId>
<version>0.5.4-SNAPSHOT</version>
- <relativePath>../../yang/pom.xml</relativePath>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>yang-maven-plugin-spi</artifactId>
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
+
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
</plugin>
</plugins>
</build>
+
</project>
* user
* @param currentModules
* yang modules parsed from yangFilesRootDir
- * @param log
- * maven logger
* @return collection of files that were generated from schema context
* @throws IOException
*/
- Collection<File> generateSources(SchemaContext context, File outputBaseDir,
- Set<Module> currentModules) throws IOException;
+ Collection<File> generateSources(SchemaContext context, File outputBaseDir, Set<Module> currentModules)
+ throws IOException;
/**
* Utilize maven logging if necessary
* Provided maven project object. Any additional information about current
* maven project can be accessed from it.
*
- * @param resourceBaseDir
+ * @param project
*/
void setMavenProject(MavenProject project);
}
<module>yang-common</module>
<module>yang-data-api</module>
<module>yang-data-util</module>
- <module>yang-data-impl</module>
+ <module>yang-data-impl</module>
<module>yang-model-api</module>
<module>yang-model-util</module>
<module>yang-binding</module>
<module>yang-ext</module>
- <module>../code-generator/yang-model-parser-api</module>
- <module>../code-generator/yang-model-parser-impl</module>
- <module>../code-generator/maven-yang</module>
- <module>../code-generator/maven-yang-plugin</module>
- <module>../code-generator/maven-yang-plugin-it</module>
+ <module>yang-model-parser-api</module>
+ <module>yang-model-parser-impl</module>
+ <module>maven-yang</module>
+ <module>maven-yang-plugin</module>
+ <module>maven-yang-plugin-it</module>
</modules>
<dependencyManagement>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>2.8.1</version>
<configuration>
<stylesheet>maven</stylesheet>
</configuration>
</plugin>
</plugins>
</build>
+
<reporting>
<plugins>
<plugin>
</plugin>
</plugins>
</reporting>
+
</project>
--- /dev/null
+<project name="${project.name}">
+
+ <skin>
+ <groupId>org.apache.maven.skins</groupId>
+ <artifactId>maven-fluido-skin</artifactId>
+ <version>1.3.0</version>
+ </skin>
+
+ <body>
+ <menu ref="parent"/>
+ <menu ref="modules"/>
+ <menu ref="reports"/>
+ </body>
+
+</project>
+
-<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">\r
- <modelVersion>4.0.0</modelVersion>\r
- <parent>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>yang</artifactId>\r
- <version>0.5.4-SNAPSHOT</version>\r
- </parent>\r
- <artifactId>yang-binding</artifactId>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+ <parent>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang</artifactId>\r
+ <version>0.5.4-SNAPSHOT</version>\r
+ </parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <artifactId>yang-binding</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>Java binding for YANG</description>\r
+\r
</project>\r
-<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">\r
- <modelVersion>4.0.0</modelVersion>\r
- <parent>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>yang</artifactId>\r
- <version>0.5.4-SNAPSHOT</version>\r
- </parent>\r
- <artifactId>yang-common</artifactId>\r
- <dependencies>\r
- <dependency>\r
- <groupId>org.slf4j</groupId>\r
- <artifactId>slf4j-api</artifactId>\r
- <version>${slf4j.version}</version>\r
- </dependency>\r
- </dependencies>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+ <parent>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang</artifactId>\r
+ <version>0.5.4-SNAPSHOT</version>\r
+ </parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <artifactId>yang-common</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>${project.artifactId}</description>\r
+\r
+ <dependencies>\r
+ <dependency>\r
+ <groupId>org.slf4j</groupId>\r
+ <artifactId>slf4j-api</artifactId>\r
+ </dependency>\r
+ </dependencies>\r
+\r
</project>\r
+\r
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
- <modelVersion>4.0.0</modelVersion>\r
+\r
<parent>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang</artifactId>\r
<version>0.5.4-SNAPSHOT</version>\r
</parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
<artifactId>yang-data-api</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>${project.artifactId}</description>\r
\r
<dependencies>\r
<dependency>\r
<artifactId>yang-common</artifactId>\r
</dependency>\r
</dependencies>\r
-</project>
\ No newline at end of file
+\r
+</project>\r
* \r
* \r
*/\r
-public interface CompositeNode extends Node<List<Node<?>>> {\r
+public interface CompositeNode extends Node<List<Node<?>>>, NodeModification {\r
\r
List<Node<?>> getChildren();\r
\r
\r
SimpleNode<?> getFirstSimpleByName(QName leaf);\r
\r
+ /**\r
+ * @return cast self to mutable, if possible \r
+ */\r
+ MutableCompositeNode asMutable();\r
}\r
* update internal map\r
*/\r
public void init();\r
+ \r
+ /**\r
+ * @return original node, if available\r
+ */\r
+ CompositeNode getOriginal();\r
}\r
*/\r
public interface MutableSimpleNode<T> extends MutableNode<T>, SimpleNode<T> {\r
\r
- // nothing\r
+ /**\r
+ * @return original node, if available\r
+ */\r
+ SimpleNode<T> getOriginal();\r
\r
}\r
* \r
* @param <T>\r
*/\r
-public interface SimpleNode<T> extends Node<T> {\r
+public interface SimpleNode<T> extends Node<T>, NodeModification {\r
\r
+ /**\r
+ * @return cast self to mutable, if possible \r
+ */\r
+ MutableSimpleNode<T> asMutable();\r
}\r
-<project xmlns="http://maven.apache.org/POM/4.0.0"\r
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
- <modelVersion>4.0.0</modelVersion>\r
+\r
<parent>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang</artifactId>\r
<version>0.5.4-SNAPSHOT</version>\r
</parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
<artifactId>yang-data-impl</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>${project.artifactId}</description>\r
\r
<properties>\r
- <groovy.version>2.1.5</groovy.version>\r
+ <groovy.version>2.1.6</groovy.version>\r
</properties>\r
-\r
<build>\r
<plugins>\r
<plugin>\r
<groupId>org.apache.maven.plugins</groupId>\r
<artifactId>maven-surefire-plugin</artifactId>\r
<configuration>\r
- <argLine>-Dlog4j.configuration=log4j-test.xml</argLine>\r
+ <argLine>-Dlog4j.configuration=log4j-test.xml -Xmx1500m</argLine>\r
<redirectTestOutputToFile>true</redirectTestOutputToFile>\r
</configuration>\r
</plugin>\r
</plugins>\r
</build>\r
\r
-\r
<dependencies>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang-model-parser-impl</artifactId>\r
+ <exclusions>\r
+ <exclusion>\r
+ <groupId>org.slf4j</groupId>\r
+ <artifactId>slf4j-simple</artifactId>\r
+ </exclusion>\r
+ </exclusions>\r
</dependency>\r
<dependency>\r
<groupId>com.google.guava</groupId>\r
<artifactId>guava</artifactId>\r
<version>14.0.1</version>\r
</dependency>\r
+ \r
<dependency>\r
<groupId>junit</groupId>\r
<artifactId>junit</artifactId>\r
<version>${groovy.version}</version>\r
<scope>test</scope>\r
</dependency>\r
+ <dependency>\r
+ <groupId>xmlunit</groupId>\r
+ <artifactId>xmlunit</artifactId>\r
+ <version>1.4</version>\r
+ <scope>test</scope>\r
+ </dependency>\r
</dependencies>\r
+\r
</project>\r
\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
\r
/**\r
* @author michal.rehak\r
* type of node value\r
* \r
*/\r
-public abstract class AbstractNodeTO<T> implements Node<T> {\r
+public abstract class AbstractNodeTO<T> implements Node<T>, NodeModification {\r
\r
private QName qName;\r
private CompositeNode parent;\r
private T value;\r
-\r
+ private ModifyAction modifyAction;\r
+ \r
/**\r
* @param qname\r
* @param parent\r
this.parent = parent;\r
this.value = value;\r
}\r
+ \r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction \r
+ */\r
+ public AbstractNodeTO(QName qname, CompositeNode parent, T value, ModifyAction modifyAction) {\r
+ this.qName = qname;\r
+ this.parent = parent;\r
+ this.value = value;\r
+ this.modifyAction = modifyAction;\r
+ }\r
\r
@Override\r
public QName getNodeType() {\r
/**\r
* @return the qName\r
*/\r
- protected QName getQName() {\r
+ public QName getQName() {\r
return qName;\r
}\r
\r
public T getValue() {\r
return value;\r
}\r
+\r
+ /**\r
+ * @return modification action\r
+ * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
+ */\r
+ @Override\r
+ public ModifyAction getModificationAction() {\r
+ return modifyAction;\r
+ }\r
+\r
+ /**\r
+ * @param modifyAction\r
+ * the modifyAction to set\r
+ */\r
+ protected void setModificationAction(ModifyAction modifyAction) {\r
+ this.modifyAction = modifyAction;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ StringBuffer out = new StringBuffer();\r
+ out.append(String.format("Node[%s], qName[%s], modify[%s]", \r
+ getClass().getSimpleName(), getQName().getLocalName(),\r
+ getModificationAction() == null ? "n/a" : getModificationAction()));\r
+ return out.toString();\r
+ }\r
+\r
+ /* */\r
+ @Override\r
+ public int hashCode() {\r
+ final int prime = 31;\r
+ int result = 1;\r
+ result = prime * result\r
+ + ((modifyAction == null) ? 0 : modifyAction.hashCode());\r
+// result = prime * result + ((parent == null) ? 0 : parent.hashCode());\r
+ result = prime * result + ((qName == null) ? 0 : qName.hashCode());\r
+ result = prime * result + ((value == null) ? 0 : value.hashCode());\r
+ return result % 2;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj)\r
+ return true;\r
+ if (obj == null)\r
+ return false;\r
+ if (getClass() != obj.getClass())\r
+ return false;\r
+ @SuppressWarnings("unchecked")\r
+ AbstractNodeTO<T> other = (AbstractNodeTO<T>) obj;\r
+ if (modifyAction != other.modifyAction)\r
+ return false;\r
+ if (parent == null) {\r
+ if (other.parent != null)\r
+ return false;\r
+ } else if (other.parent == null) {\r
+ return false;\r
+ } \r
+ if (qName == null) {\r
+ if (other.qName != null)\r
+ return false;\r
+ } else if (!qName.equals(other.qName))\r
+ return false;\r
+ if (value == null) {\r
+ if (other.value != null)\r
+ return false;\r
+ } else if (!value.equals(other.value))\r
+ return false;\r
+ return true;\r
+ }\r
+ /* */\r
+ \r
}\r
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
*/\r
package org.opendaylight.controller.yang.data.impl;\r
\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
import org.opendaylight.controller.yang.data.api.ModifyAction;\r
import org.opendaylight.controller.yang.data.api.Node;\r
-import org.opendaylight.controller.yang.data.api.NodeModification;\r
\r
/**\r
* @author michal.rehak\r
* \r
*/\r
-public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl\r
- implements NodeModification {\r
-\r
- private ModifyAction modifyAction;\r
+public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl {\r
\r
/**\r
* @param qname\r
public CompositeNodeModificationTOImpl(QName qname, CompositeNode parent,\r
List<Node<?>> value, ModifyAction modifyAction) {\r
super(qname, parent, value);\r
- this.modifyAction = modifyAction;\r
- }\r
-\r
- /**\r
- * @return modification action\r
- * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
- */\r
- @Override\r
- public ModifyAction getModificationAction() {\r
- return modifyAction;\r
+ super.setModificationAction(modifyAction);\r
}\r
-\r
- /**\r
- * @param modifyAction\r
- * the modifyAction to set\r
- */\r
- protected void setModificationAction(ModifyAction modifyAction) {\r
- this.modifyAction = modifyAction;\r
- }\r
-\r
}\r
\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
import org.opendaylight.controller.yang.data.api.Node;\r
import org.opendaylight.controller.yang.data.api.SimpleNode;\r
\r
if (value != null) {\r
nodeMap = NodeUtils.buildNodeMap(getValue());\r
}\r
+ init();\r
+ }\r
+\r
+ /**\r
+ * @param qname\r
+ * @param parent use null to create top composite node (without parent)\r
+ * @param value\r
+ * @param modifyAction \r
+ */\r
+ public CompositeNodeTOImpl(QName qname, CompositeNode parent,\r
+ List<Node<?>> value, ModifyAction modifyAction) {\r
+ super(qname, parent, value, modifyAction);\r
+ init();\r
}\r
\r
\r
\r
@Override\r
public List<CompositeNode> getCompositesByName(String children) {\r
- return getCompositesByName(localQName(children));\r
+ return getCompositesByName(new QName(getNodeType(), children));\r
}\r
\r
@Override\r
public List<SimpleNode<?>> getSimpleNodesByName(String children) {\r
- return getSimpleNodesByName(localQName(children));\r
+ return getSimpleNodesByName(new QName(getNodeType(), children));\r
}\r
\r
- private QName localQName(String str) {\r
- return new QName(getNodeType(), str);\r
+ /**\r
+ * @param value\r
+ */\r
+ protected void init() {\r
+ if (getValue() != null) {\r
+ nodeMap = NodeUtils.buildNodeMap(getValue());\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public MutableCompositeNode asMutable() {\r
+ throw new IllegalAccessError("cast to mutable is not supported - "+getClass().getSimpleName());\r
}\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return super.toString() + ", children.size = " \r
+ + (getChildren() != null ? getChildren().size() : "n/a");\r
+ }\r
+ \r
+ \r
\r
}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Stack;\r
+\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableNode;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class LazyNodeToNodeMap {\r
+ \r
+ private Map<Node<?>, Node<?>> node2node = new HashMap<>();\r
+ private CompositeNode originalRoot;\r
+ private MutableCompositeNode mutableRoot;\r
+ \r
+ /**\r
+ * @param originalNode\r
+ * @return mutable twin\r
+ */\r
+ public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
+ Node<?> mutableNode = node2node.get(originalNode);\r
+ if (mutableNode == null) {\r
+ addPathMembers(originalNode);\r
+ mutableNode = node2node.get(originalNode);\r
+ }\r
+ \r
+ return mutableNode;\r
+ }\r
+ \r
+ /**\r
+ * @param originalNode\r
+ */\r
+ private void addPathMembers(Node<?> originalNode) {\r
+ Stack<Node<?>> jobQueue = new Stack<>(); \r
+ jobQueue.push(originalNode);\r
+ while (!jobQueue.isEmpty()) {\r
+ Node<?> node2add = jobQueue.pop();\r
+ boolean fixChildrenRefOnly = false;\r
+ if (node2node.containsKey(node2add)) {\r
+ if (node2add instanceof SimpleNode<?>) {\r
+ continue;\r
+ }\r
+ fixChildrenRefOnly = true;\r
+ }\r
+ \r
+ CompositeNode nextParent = node2add.getParent();\r
+ MutableNode<?> mutableEquivalent = null;\r
+ \r
+ if (node2add instanceof SimpleNode<?>) {\r
+ SimpleNode<?> node2addSimple = (SimpleNode<?>) node2add;\r
+ MutableSimpleNode<?> nodeMutant = NodeFactory.createMutableSimpleNode(\r
+ node2add.getNodeType(), null, node2addSimple.getValue(), \r
+ node2addSimple.getModificationAction(), node2addSimple);\r
+ mutableEquivalent = nodeMutant;\r
+ } else if (node2add instanceof CompositeNode) {\r
+ MutableCompositeNode nodeMutant = null;\r
+ if (fixChildrenRefOnly) {\r
+ nodeMutant = (MutableCompositeNode) node2node.get(node2add);\r
+ } else {\r
+ CompositeNode node2addComposite = (CompositeNode) node2add;\r
+ nodeMutant = NodeFactory.createMutableCompositeNode(node2add.getNodeType(), \r
+ null, null, \r
+ ((NodeModification) node2add).getModificationAction(), node2addComposite);\r
+ }\r
+ \r
+ mutableEquivalent = nodeMutant;\r
+\r
+ // tidy up children\r
+ if (nodeMutant.getChildren() == null) {\r
+ nodeMutant.setValue(new ArrayList<Node<?>>());\r
+ }\r
+ for (Node<?> originalChildNode : ((CompositeNode) node2add).getChildren()) {\r
+ MutableNode<?> mutableChild = (MutableNode<?>) node2node.get(originalChildNode);\r
+ fixChildrenRef(nodeMutant, mutableChild);\r
+ }\r
+ \r
+ if (nodeMutant.getChildren() != null && !nodeMutant.getChildren().isEmpty()) {\r
+ nodeMutant.init();\r
+ }\r
+\r
+ // store tree root, if occured\r
+ if (nextParent == null) {\r
+ if (originalRoot == null) {\r
+ originalRoot = (CompositeNode) node2add;\r
+ mutableRoot = nodeMutant;\r
+ } else {\r
+ if (!originalRoot.equals(node2add)) {\r
+ throw new IllegalStateException("Different tree root node obtained - " +\r
+ "perhaps nodes of different trees are getting mixed up.");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ // feed jobQueue\r
+ node2node.put(node2add, mutableEquivalent);\r
+ if (nextParent != null) {\r
+ jobQueue.push(nextParent);\r
+ } \r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param nodeMutant\r
+ * @param mutableChild\r
+ */\r
+ private static void fixChildrenRef(MutableCompositeNode nodeMutant,\r
+ MutableNode<?> mutableChild) {\r
+ if (mutableChild != null) {\r
+ if (!nodeMutant.getChildren().contains(mutableChild)) {\r
+ nodeMutant.getChildren().add(mutableChild);\r
+ }\r
+ CompositeNode parentOfChild = mutableChild.getParent();\r
+ if (parentOfChild == null) {\r
+ mutableChild.setParent(nodeMutant);\r
+ } else {\r
+ if (!parentOfChild.equals(nodeMutant)) {\r
+ throw new IllegalStateException("Different parent node obtained - " +\r
+ "perhaps nodes of different trees are getting mixed up.");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @return the mutableRoot\r
+ */\r
+ public MutableCompositeNode getMutableRoot() {\r
+ return mutableRoot;\r
+ }\r
+ \r
+ /**\r
+ * @return set of original nodes, registered in map as keys \r
+ */\r
+ public Set<Node<?>> getKeyNodes() {\r
+ return node2node.keySet();\r
+ }\r
+}\r
* @author michal.rehak\r
* \r
*/\r
-public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl\r
+public class MutableCompositeNodeTOImpl extends CompositeNodeTOImpl\r
implements MutableCompositeNode {\r
\r
private Map<QName, List<Node<?>>> nodeMap;\r
+ private CompositeNode original;\r
\r
/**\r
* @param qname\r
*/\r
@Override\r
public void init() {\r
- nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+ if (!getChildren().isEmpty()) {\r
+ nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+ }\r
}\r
\r
@Override\r
protected Map<QName, List<Node<?>>> getNodeMap() {\r
return nodeMap;\r
}\r
+ \r
+ @Override\r
+ public MutableCompositeNode asMutable() {\r
+ return this;\r
+ }\r
+ \r
+ @Override\r
+ public CompositeNode getOriginal() {\r
+ return original;\r
+ }\r
+ \r
+ /**\r
+ * @param original the original to set\r
+ */\r
+ public void setOriginal(CompositeNode original) {\r
+ this.original = original;\r
+ }\r
}\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
import org.opendaylight.controller.yang.data.api.ModifyAction;\r
import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
\r
/**\r
* @author michal.rehak\r
* @param <T> type of simple node value\r
* \r
*/\r
-public class MutableSimpleNodeTOImpl<T> extends SimpleNodeModificationTOImpl<T> \r
+public class MutableSimpleNodeTOImpl<T> extends SimpleNodeTOImpl<T> \r
implements MutableSimpleNode<T> {\r
\r
+ private SimpleNode<T> original;\r
+\r
/**\r
* @param qname\r
* @param parent\r
public void setModifyAction(ModifyAction action) {\r
super.setModificationAction(action);\r
}\r
+ \r
+ @Override\r
+ public MutableSimpleNode<T> asMutable() {\r
+ return this;\r
+ }\r
+ \r
+ @Override\r
+ public SimpleNode<T> getOriginal() {\r
+ return original;\r
+ }\r
+ \r
+ /**\r
+ * @param original the original to set\r
+ */\r
+ public void setOriginal(SimpleNode<T> original) {\r
+ this.original = original;\r
+ }\r
}\r
import java.util.AbstractMap.SimpleEntry;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
+import java.util.HashMap;\r
import java.util.List;\r
import java.util.Map;\r
import java.util.Stack;\r
import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
import org.opendaylight.controller.yang.data.api.SimpleNode;\r
\r
/**\r
* @param value\r
* @return simple node modification, based on given qname, value and parent\r
*/\r
- public static <T> SimpleNode<T> createSimpleNode(QName qName,\r
+ public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
CompositeNode parent, T value) {\r
- SimpleNodeTOImpl<T> simpleNodeTOImpl = new SimpleNodeTOImpl<T>(qName, parent, value);\r
- return simpleNodeTOImpl;\r
+ return createImmutableSimpleNode(qName, parent, value, null);\r
}\r
\r
/**\r
* @param qName\r
* @param parent\r
* @param value\r
+ * @param modifyAction \r
+ * @param original originating node, if available\r
* @return simple node modification, based on given qname, value and parent\r
*/\r
public static <T> MutableSimpleNode<T> createMutableSimpleNode(QName qName,\r
- CompositeNode parent, T value) {\r
+ CompositeNode parent, Object value, ModifyAction modifyAction, SimpleNode<T> original) {\r
+ @SuppressWarnings("unchecked")\r
MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = \r
- new MutableSimpleNodeTOImpl<T>(qName, parent, value, null);\r
+ new MutableSimpleNodeTOImpl<T>(qName, parent, (T) value, modifyAction);\r
+ simpleNodeTOImpl.setOriginal(original);\r
return simpleNodeTOImpl;\r
}\r
-\r
+ \r
/**\r
* @param qName\r
* @param parent\r
* @param value\r
* @return composite node modification, based on given qname, value (children), parent and modifyAction\r
*/\r
- public static CompositeNode createCompositeNode(QName qName,\r
+ public static CompositeNode createImmutableCompositeNode(QName qName,\r
CompositeNode parent, List<Node<?>> value) {\r
- CompositeNode compositeNodeTOImpl = new CompositeNodeTOImpl(qName, parent, value);\r
- return compositeNodeTOImpl;\r
+ return createImmutableCompositeNode(qName, parent, value, null);\r
}\r
\r
/**\r
* @param qName\r
* @param parent\r
- * @param value\r
- * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
+ * @param valueArg \r
+ * @param modifyAction \r
+ * @param original originating node, if available\r
+ * @return composite node modification, based on given qName, value (children), parent and modifyAction\r
*/\r
public static MutableCompositeNode createMutableCompositeNode(QName qName,\r
- CompositeNode parent, List<Node<?>> value) {\r
+ CompositeNode parent, List<Node<?>> valueArg, ModifyAction modifyAction, CompositeNode original) {\r
+ List<Node<?>> value = valueArg;\r
+ if (value == null) {\r
+ value = new ArrayList<>();\r
+ }\r
MutableCompositeNodeTOImpl compositeNodeTOImpl = \r
- new MutableCompositeNodeTOImpl(qName, parent, value, null);\r
+ new MutableCompositeNodeTOImpl(qName, parent, value, modifyAction);\r
+ compositeNodeTOImpl.setOriginal(original);\r
return compositeNodeTOImpl;\r
}\r
\r
* @param modifyAction\r
* @return simple node modification, based on given qname, value, parent and modifyAction\r
*/\r
- public static <T> SimpleNodeModificationTOImpl<T> createSimpleNodeModification(QName qName,\r
+ public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
CompositeNode parent, T value, ModifyAction modifyAction) {\r
- SimpleNodeModificationTOImpl<T> simpleNodeModTOImpl = \r
- new SimpleNodeModificationTOImpl<T>(qName, parent, value, modifyAction);\r
+ SimpleNodeTOImpl<T> simpleNodeModTOImpl = \r
+ new SimpleNodeTOImpl<T>(qName, parent, value, modifyAction);\r
return simpleNodeModTOImpl;\r
}\r
\r
* @param modifyAction \r
* @return composite node modification, based on given qname, value (children), parent and modifyAction\r
*/\r
- public static CompositeNodeModificationTOImpl createCompositeNodeModification(QName qName,\r
+ public static CompositeNode createImmutableCompositeNode(QName qName,\r
CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {\r
- CompositeNodeModificationTOImpl compositeNodeModTOImpl = \r
- new CompositeNodeModificationTOImpl(qName, parent, value, modifyAction);\r
+ CompositeNodeTOImpl compositeNodeModTOImpl = \r
+ new CompositeNodeTOImpl(qName, parent, value, modifyAction);\r
return compositeNodeModTOImpl;\r
}\r
\r
* has no reference to this copy \r
*/\r
public static <T> SimpleNode<T> copyNode(SimpleNode<T> node) {\r
- SimpleNode<T> twinNode = createSimpleNode(\r
+ SimpleNode<T> twinNode = createImmutableSimpleNode(\r
node.getNodeType(), node.getParent(), node.getValue());\r
return twinNode;\r
}\r
* @return copy of given node, parent and value are the same, but parent \r
* has no reference to this copy \r
*/\r
- public static <T> SimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
- SimpleNode<T> twinNode = createMutableSimpleNode(\r
- node.getNodeType(), node.getParent(), node.getValue());\r
+ public static <T> MutableSimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
+ MutableSimpleNode<T> twinNode = createMutableSimpleNode(\r
+ node.getNodeType(), node.getParent(), node.getValue(), \r
+ node.getModificationAction(), null);\r
return twinNode;\r
}\r
-\r
+ \r
/**\r
* @param node\r
* @param children \r
* have no reference to this copy\r
*/\r
public static CompositeNode copyNode(CompositeNode node, Node<?>... children) {\r
- CompositeNode twinNode = createCompositeNode(\r
- node.getNodeType(), node.getParent(), Arrays.asList(children));\r
+ CompositeNode twinNode = createImmutableCompositeNode(\r
+ node.getNodeType(), node.getParent(), Arrays.asList(children), node.getModificationAction());\r
return twinNode;\r
}\r
\r
\r
/**\r
* @param node root of original tree\r
- * @param originalToMutable (optional) empty map, where binding between original and copy \r
+ * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
* will be stored\r
- * @return copy of given node, parent and children are the same, but parent and children \r
- * have no reference to this copy\r
+ * @return copy of given node and all subnodes recursively\r
*/\r
- public static MutableCompositeNode copyDeepNode(CompositeNode node, \r
- Map<Node<?>, Node<?>> originalToMutable) {\r
- \r
- MutableCompositeNode mutableRoot = \r
- createMutableCompositeNode(node.getNodeType(), null, null);\r
- Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
- jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
- if (originalToMutable != null) {\r
- originalToMutable.put(node, mutableRoot);\r
- }\r
- \r
- while (!jobQueue.isEmpty()) {\r
- SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
- CompositeNode originalNode = job.getKey();\r
- MutableCompositeNode mutableNode = job.getValue();\r
- mutableNode.setValue(new ArrayList<Node<?>>());\r
- \r
- for (Node<?> child : originalNode.getChildren()) {\r
- Node<?> mutableAscendant = null;\r
- if (child instanceof CompositeNode) {\r
- MutableCompositeNode newMutable = \r
- createMutableCompositeNode(child.getNodeType(), mutableNode, null);\r
- jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
- (CompositeNode) child, newMutable));\r
- mutableAscendant = newMutable;\r
- } else if (child instanceof SimpleNode<?>) {\r
- mutableAscendant = \r
- createMutableSimpleNode(child.getNodeType(), mutableNode, child.getValue());\r
- } else {\r
- throw new IllegalStateException("Node class deep copy not supported: "\r
- +child.getClass().getName());\r
- }\r
- \r
- mutableNode.getChildren().add(mutableAscendant);\r
- if (originalToMutable != null) {\r
- originalToMutable.put(child, mutableAscendant);\r
- }\r
- }\r
- mutableNode.init();\r
- }\r
+ public static MutableCompositeNode copyDeepAsMutable(CompositeNode node, \r
+ Map<Node<?>, Node<?>> originalToCopyArg) {\r
+ \r
+ Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+ if (originalToCopy == null) {\r
+ originalToCopy = new HashMap<>();\r
+ }\r
+\r
+ MutableCompositeNode mutableRoot = createMutableCompositeNode(node.getNodeType(), null, null, \r
+ node.getModificationAction(), null);\r
+ Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
+ jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
+ originalToCopy.put(node, mutableRoot);\r
+\r
+ while (!jobQueue.isEmpty()) {\r
+ SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
+ CompositeNode originalNode = job.getKey();\r
+ MutableCompositeNode mutableNode = job.getValue();\r
+ mutableNode.setValue(new ArrayList<Node<?>>());\r
+\r
+ for (Node<?> child : originalNode.getChildren()) {\r
+ Node<?> mutableAscendant = null;\r
+ if (child instanceof CompositeNode) {\r
+ MutableCompositeNode newMutable = \r
+ createMutableCompositeNode(child.getNodeType(), mutableNode, null, \r
+ ((NodeModification) child).getModificationAction(), null);\r
+ jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
+ (CompositeNode) child, newMutable));\r
+ mutableAscendant = newMutable;\r
+ } else if (child instanceof SimpleNode<?>) {\r
+ mutableAscendant = \r
+ createMutableSimpleNode(child.getNodeType(), mutableNode, \r
+ child.getValue(), \r
+ ((NodeModification) child).getModificationAction(), null);\r
+ } else {\r
+ throw new IllegalStateException("Node class deep copy not supported: "\r
+ +child.getClass().getName());\r
+ }\r
+\r
+ mutableNode.getChildren().add(mutableAscendant);\r
+ originalToCopy.put(child, mutableAscendant);\r
+ }\r
+ mutableNode.init();\r
+ }\r
+\r
+ return mutableRoot;\r
+ }\r
+ \r
+ /**\r
+ * @param node root of original tree\r
+ * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
+ * will be stored\r
+ * @return copy of given node and all subnodes recursively\r
+ */\r
+ public static CompositeNode copyDeepAsImmutable(CompositeNode node, \r
+ Map<Node<?>, Node<?>> originalToCopyArg) {\r
+ Stack<CompositeNode> jobQueue = new Stack<>();\r
+ jobQueue.push(node);\r
+ \r
+ Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+ if (originalToCopy == null) {\r
+ originalToCopy = new HashMap<>();\r
+ }\r
+ \r
+ while (!jobQueue.isEmpty()) {\r
+ CompositeNode jobNode = jobQueue.peek();\r
+ if (!originalToCopy.isEmpty() \r
+ && originalToCopy.keySet().containsAll(jobNode.getChildren())) {\r
+ jobQueue.pop();\r
+ List<Node<?>> newChildren = NodeUtils.collectMapValues(jobNode.getChildren(), originalToCopy);\r
+ CompositeNode nodeCopy = createImmutableCompositeNode(jobNode.getNodeType(), null, \r
+ newChildren, jobNode.getModificationAction());\r
+ NodeUtils.fixChildrenRelation(nodeCopy);\r
+ originalToCopy.put(jobNode, nodeCopy);\r
+ } else {\r
+ for (Node<?> child : jobNode.getChildren()) {\r
+ if (child instanceof SimpleNode<?>) {\r
+ originalToCopy.put(child, createImmutableSimpleNode(\r
+ child.getNodeType(), null, child.getValue(), \r
+ ((NodeModification) child).getModificationAction()));\r
+ } else if (child instanceof CompositeNode) {\r
+ jobQueue.push((CompositeNode) child);\r
+ }\r
+ }\r
+ }\r
+ }\r
\r
- return mutableRoot;\r
+ return (CompositeNode) originalToCopy.get(node);\r
}\r
\r
}\r
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
*/\r
package org.opendaylight.controller.yang.data.impl;\r
\r
-import java.util.HashMap;\r
import java.util.HashSet;\r
import java.util.List;\r
import java.util.Map;\r
import java.util.Set;\r
-import java.util.Stack;\r
\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
private SchemaContext context;\r
\r
private Set<MutableNode<?>> changeLog;\r
- private Map<Node<?>, Node<?>> originalToMutable;\r
-\r
- private MutableCompositeNode mutableRoot;\r
+ private LazyNodeToNodeMap originalToMutable;\r
\r
/**\r
* @param originalTreeRootNode \r
*/\r
public NodeModificationBuilderImpl(CompositeNode originalTreeRootNode, SchemaContext context) {\r
this.context = context;\r
- originalToMutable = new HashMap<>();\r
- mutableRoot = NodeFactory.copyDeepNode(originalTreeRootNode, originalToMutable);\r
+ originalToMutable = new LazyNodeToNodeMap();\r
changeLog = new HashSet<>();\r
}\r
\r
- /**\r
- * add given node to it's parent's list of children\r
- * @param newNode\r
- */\r
- private static void fixParentRelation(Node<?> newNode) {\r
- if (newNode.getParent() != null) {\r
- List<Node<?>> siblings = newNode.getParent().getChildren();\r
- if (!siblings.contains(newNode)) {\r
- siblings.add(newNode);\r
- }\r
- }\r
- }\r
-\r
/**\r
* @param modNode\r
* @param action \r
\r
@Override\r
public void addNode(MutableSimpleNode<?> newNode) {\r
- fixParentRelation(newNode);\r
+ NodeUtils.fixParentRelation(newNode);\r
addModificationToLog(newNode, ModifyAction.CREATE);\r
}\r
\r
@Override\r
public void addNode(MutableCompositeNode newNode) {\r
- fixParentRelation(newNode);\r
+ NodeUtils.fixParentRelation(newNode);\r
addModificationToLog(newNode, ModifyAction.CREATE);\r
}\r
\r
wanted.addAll(collectSelfAndAllParents(mutant));\r
}\r
\r
- // TODO:: walk wanted and add relevant keys\r
+ // walk wanted and add relevant keys\r
Map<String, ListSchemaNode> mapOfLists = NodeUtils.buildMapOfListNodes(context);\r
- Set<Node<?>> wantedKeys = new HashSet<>();\r
for (Node<?> outlaw : wanted) {\r
if (outlaw instanceof CompositeNode) {\r
String path = NodeUtils.buildPath(outlaw);\r
if (listSchema.getQName().equals(outlaw.getNodeType())) {\r
// try to add key subnode to wanted list\r
List<QName> supportedKeys = listSchema.getKeyDefinition();\r
- for (Node<?> outlawChildren : ((CompositeNode) outlaw).getChildren()) {\r
- if (supportedKeys.contains(outlawChildren.getNodeType())) {\r
- wantedKeys.add(outlawChildren);\r
+ CompositeNode outlawOriginal = ((MutableCompositeNode) outlaw).getOriginal();\r
+ for (Node<?> outlawOriginalChild : outlawOriginal.getChildren()) {\r
+ if (supportedKeys.contains(outlawOriginalChild.getNodeType())) {\r
+ originalToMutable.getMutableEquivalent(outlawOriginalChild);\r
}\r
}\r
}\r
}\r
}\r
}\r
- wanted.addAll(wantedKeys);\r
- \r
- // remove all unwanted nodes from tree\r
- removeUnrelevantNodes(mutableRoot, wanted);\r
\r
- return mutableRoot;\r
- }\r
-\r
- /**\r
- * @param mutableRoot2\r
- * @param wanted\r
- */\r
- private static void removeUnrelevantNodes(MutableCompositeNode mutRoot,\r
- Set<Node<?>> wanted) {\r
- Stack<MutableNode<?>> jobQueue = new Stack<>();\r
- jobQueue.push(mutRoot);\r
- while (!jobQueue.isEmpty()) {\r
- MutableNode<?> mutNode = jobQueue.pop();\r
- if (!wanted.contains(mutNode)) {\r
- if (mutNode.getParent() != null) {\r
- mutNode.getParent().getChildren().remove(mutNode);\r
- }\r
- } else {\r
- if (mutNode instanceof MutableCompositeNode) {\r
- for (Node<?> mutChild : ((MutableCompositeNode) mutNode).getChildren()) {\r
- jobQueue.push((MutableNode<?>) mutChild);\r
- }\r
- }\r
- }\r
- }\r
+ return originalToMutable.getMutableRoot();\r
}\r
\r
/**\r
- * @param focusedAncestor\r
+ * @param focusedDescendant\r
* @return set of parents and focusedAncestor itself\r
*/\r
- private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedAncestor) {\r
+ private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedDescendant) {\r
Set<Node<?>> family = new HashSet<>();\r
- Node<?> tmpNode = focusedAncestor;\r
+ Node<?> tmpNode = focusedDescendant;\r
while (tmpNode != null) {\r
family.add(tmpNode);\r
tmpNode = tmpNode.getParent();\r
*/\r
@Override\r
public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
- return originalToMutable.get(originalNode);\r
+ return originalToMutable.getMutableEquivalent(originalNode);\r
}\r
\r
}\r
import org.opendaylight.controller.yang.model.api.SchemaContext;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
-import org.w3c.dom.Document;\r
import org.w3c.dom.Element;\r
\r
import com.google.common.base.Joiner;\r
+import com.google.common.collect.Lists;\r
\r
\r
/**\r
*/\r
public abstract class NodeUtils {\r
\r
+ private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);\r
+ \r
/**\r
* \r
*/\r
private static final String USER_KEY_NODE = "node";\r
- private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);\r
\r
/**\r
* @param node\r
* @return dom tree, containing same node structure, yang nodes are associated \r
* to dom nodes as user data\r
*/\r
- public static Document buildShadowDomTree(CompositeNode treeRootNode) {\r
+ public static org.w3c.dom.Document buildShadowDomTree(CompositeNode treeRootNode) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
- Document doc = null;\r
+ org.w3c.dom.Document doc = null;\r
try {\r
DocumentBuilder bob = dbf.newDocumentBuilder();\r
doc = bob.newDocument();\r
return null;\r
}\r
\r
+ \r
Stack<SimpleEntry<org.w3c.dom.Node, Node<?>>> jobQueue = new Stack<>();\r
jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(doc, treeRootNode));\r
\r
SimpleEntry<org.w3c.dom.Node, Node<?>> job = jobQueue.pop();\r
org.w3c.dom.Node jointPlace = job.getKey();\r
Node<?> item = job.getValue();\r
- Element itemEl = doc.createElement(item.getNodeType().getLocalName());\r
+ QName nodeType = item.getNodeType();\r
+ Element itemEl = doc.createElementNS(nodeType.getNamespace().toString(), \r
+ item.getNodeType().getLocalName());\r
itemEl.setUserData(USER_KEY_NODE, item, null);\r
if (item instanceof SimpleNode<?>) {\r
Object value = ((SimpleNode<?>) item).getValue();\r
itemEl.setTextContent(String.valueOf(value));\r
- itemEl.setAttribute("type", value.getClass().getSimpleName());\r
+ //itemEl.setAttribute("type", value.getClass().getSimpleName());\r
}\r
if (item instanceof NodeModification) {\r
ModifyAction modificationAction = ((NodeModification) item).getModificationAction();\r
* @throws XPathExpressionException\r
*/\r
@SuppressWarnings("unchecked")\r
- public static <T> T findNodeByXpath(Document doc, String xpathEx) \r
+ public static <T> T findNodeByXpath(org.w3c.dom.Document doc, String xpathEx) \r
throws XPathExpressionException {\r
T userNode = null;\r
XPathFactory xPathfactory = XPathFactory.newInstance();\r
\r
return mapOfLists;\r
}\r
-\r
-\r
+ \r
/**\r
* @param path\r
* @return\r
}\r
return Joiner.on(".").join(pathSeed);\r
}\r
+\r
+ /**\r
+ * add given node to it's parent's list of children\r
+ * @param newNode\r
+ */\r
+ public static void fixParentRelation(Node<?> newNode) {\r
+ if (newNode.getParent() != null) {\r
+ List<Node<?>> siblings = newNode.getParent().getChildren();\r
+ if (!siblings.contains(newNode)) {\r
+ siblings.add(newNode);\r
+ }\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * crawl all children of given node and assign it as their parent\r
+ * @param parentNode\r
+ */\r
+ public static void fixChildrenRelation(CompositeNode parentNode) {\r
+ if (parentNode.getChildren() != null) {\r
+ for (Node<?> child : parentNode.getChildren()) {\r
+ if (child instanceof AbstractNodeTO<?>) {\r
+ ((AbstractNodeTO<?>) child).setParent(parentNode);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * @param keys\r
+ * @param dataMap\r
+ * @return list of values of map, found by given keys \r
+ */\r
+ public static <T, K> List<K> collectMapValues(List<T> keys,\r
+ Map<T, K> dataMap) {\r
+ List<K> valueSubList = new ArrayList<>();\r
+ for (T key : keys) {\r
+ valueSubList.add(dataMap.get(key));\r
+ }\r
+ \r
+ return valueSubList;\r
+ }\r
+ \r
+ /**\r
+ * @param nodes\r
+ * @return list of children in list of appropriate type\r
+ */\r
+ public static List<Node<?>> buildChildrenList(Node<?>...nodes) {\r
+ return Lists.newArrayList(nodes);\r
+ }\r
+\r
}\r
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
*/\r
package org.opendaylight.controller.yang.data.impl;\r
\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
import org.opendaylight.controller.yang.data.api.ModifyAction;\r
-import org.opendaylight.controller.yang.data.api.NodeModification;\r
\r
/**\r
* @author michal.rehak\r
* @param <T> type of node value\r
* \r
*/\r
-public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T>\r
- implements NodeModification {\r
-\r
- private ModifyAction modifyAction;\r
+public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T> {\r
\r
/**\r
* @param qname\r
public SimpleNodeModificationTOImpl(QName qname, CompositeNode parent,\r
T value, ModifyAction modifyAction) {\r
super(qname, parent, value);\r
- this.modifyAction = modifyAction;\r
- }\r
-\r
- /**\r
- * @return modification action\r
- * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
- */\r
- @Override\r
- public ModifyAction getModificationAction() {\r
- return modifyAction;\r
- }\r
-\r
- /**\r
- * @param modifyAction\r
- * the modifyAction to set\r
- */\r
- protected void setModificationAction(ModifyAction modifyAction) {\r
- this.modifyAction = modifyAction;\r
+ setModificationAction(modifyAction);\r
}\r
}\r
\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
import org.opendaylight.controller.yang.data.api.SimpleNode;\r
\r
/**\r
public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value) {\r
super(qname, parent, value);\r
}\r
+ \r
+ /**\r
+ * @param qname\r
+ * @param parent\r
+ * @param value\r
+ * @param modifyAction \r
+ */\r
+ public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value, ModifyAction modifyAction) {\r
+ super(qname, parent, value, modifyAction);\r
+ }\r
\r
+ \r
+ @Override\r
+ public MutableSimpleNode<T> asMutable() {\r
+ throw new IllegalAccessError("cast to mutable is not supported - "+getClass().getSimpleName());\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return super.toString() + ", value = "+getValue();\r
+ }\r
}\r
--- /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.yang.data.impl;
+
+import org.custommonkey.xmlunit.Difference;
+import org.custommonkey.xmlunit.DifferenceConstants;
+import org.custommonkey.xmlunit.DifferenceListener;
+
+/**
+ * Implementatin of {@link DifferenceListener} ignoring white characters around text elements
+ * @author mirehak
+ *
+ */
+public class IgnoreWhiteCharsDiffListener implements DifferenceListener {
+
+ @Override
+ public void skippedComparison(org.w3c.dom.Node control,
+ org.w3c.dom.Node test) {
+ // do nothing
+ }
+
+ @Override
+ public int differenceFound(Difference diff) {
+
+ if (diff.getId() == DifferenceConstants.TEXT_VALUE.getId()) {
+
+ String control = diff.getControlNodeDetail().getValue();
+ if (control != null) {
+ control = control.trim();
+ if (diff.getTestNodeDetail().getValue() != null
+ && control.equals(diff.getTestNodeDetail().getValue().trim())) {
+ return
+ DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR;
+ }
+ }
+ }
+ return RETURN_ACCEPT_DIFFERENCE;
+ }
+}
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class LazyNodeToNodeMapTest {\r
+ \r
+ private LazyNodeToNodeMap lazyN2N;\r
+ private CompositeNode tree;\r
+\r
+ /**\r
+ * prepare test values\r
+ * @throws Exception \r
+ */\r
+ @Before\r
+ public void setUp() throws Exception {\r
+ lazyN2N = new LazyNodeToNodeMap();\r
+ \r
+ QName qName = new QName(\r
+ new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
+ new Date(42), "yang-data-impl-mutableTest");\r
+ \r
+ tree = NodeHelper.buildTestConfigTree(qName);\r
+ }\r
+\r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.LazyNodeToNodeMap#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}.\r
+ */\r
+ @Test\r
+ public void testGetMutableEquivalent() {\r
+ MutableCompositeNode mutableTree = (MutableCompositeNode) lazyN2N.getMutableEquivalent(tree);\r
+ \r
+ Assert.assertNull(mutableTree.getParent());\r
+ Assert.assertEquals(tree.getNodeType(), mutableTree.getNodeType());\r
+ Assert.assertEquals(1, lazyN2N.getKeyNodes().size());\r
+ \r
+ Node<?> subNode = tree.getCompositesByName("topologies").iterator().next();\r
+ Node<?> subMutant = lazyN2N.getMutableEquivalent(subNode);\r
+ \r
+ Assert.assertNotNull(subMutant.getParent());\r
+ Assert.assertEquals(subNode.getNodeType(), subMutant.getNodeType());\r
+ Assert.assertEquals(2, lazyN2N.getKeyNodes().size());\r
+ \r
+ Assert.assertEquals(mutableTree, subMutant.getParent());\r
+ Assert.assertEquals(mutableTree.getChildren().size(), 1);\r
+ Assert.assertEquals(mutableTree.getChildren().iterator().next(), subMutant);\r
+ }\r
+\r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.LazyNodeToNodeMap#getMutableRoot()}.\r
+ */\r
+ @Test\r
+ public void testGetMutableRoot() {\r
+ Node<?> subNode = tree.getCompositesByName("topologies").iterator().next();\r
+ Node<?> subMutant = lazyN2N.getMutableEquivalent(subNode);\r
+ \r
+ Assert.assertNotNull(subMutant.getParent());\r
+ Assert.assertEquals(subMutant.getParent(), lazyN2N.getMutableRoot());\r
+ }\r
+\r
+}\r
--- /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.yang.data.impl;
+
+/**
+ * Provides memory consumption and elapsed time between 2 points
+ * @author mirehak
+ */
+public class MemoryConsumption {
+
+ private long memBegin;
+ private long tsBegin;
+
+ /**
+ * record memory and timestamp
+ */
+ public void startObserving() {
+ Runtime runtime = Runtime.getRuntime();
+ // Run the garbage collector
+ runtime.gc();
+ memBegin = getActualMemoryConsumption();
+ tsBegin = System.currentTimeMillis();
+ }
+
+
+ /**
+ * @return memory usage and time elapsed message
+ */
+ public String finishObserving() {
+ long memEnd = getActualMemoryConsumption();
+ long tsEnd = System.currentTimeMillis();
+ return String.format("Used memory: %10d B; Elapsed time: %5d ms", (memEnd - memBegin), (tsEnd - tsBegin));
+ }
+
+
+ /**
+ * @return actual memory usage
+ */
+ public static long getActualMemoryConsumption() {
+ Runtime runtime = Runtime.getRuntime();
+ // Calculate the used memory
+ long memory = runtime.totalMemory() - runtime.freeMemory();
+ return memory;
+ }
+
+
+}
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import groovy.util.BuilderSupport;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.util.Date;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class MyNodeBuilder extends BuilderSupport {\r
+ \r
+ private static final Logger LOG = LoggerFactory\r
+ .getLogger(MyNodeBuilder.class);\r
+\r
+ private URI qnNamespace;\r
+ private String qnPrefix;\r
+ private Date qnRevision;\r
+ \r
+ private CompositeNode rootNode;\r
+\r
+ /**\r
+ * @param baseQName\r
+ */\r
+ private MyNodeBuilder(QName baseQName) {\r
+ qnNamespace = baseQName.getNamespace();\r
+ qnPrefix = baseQName.getPrefix();\r
+ qnRevision = baseQName.getRevision();\r
+ }\r
+\r
+ /**\r
+ * @return initialized singleton instance\r
+ */\r
+ public static MyNodeBuilder newInstance() {\r
+ QName qName = null;\r
+ try {\r
+ qName = new QName(\r
+ new URI("urn:opendaylight:controller:network"), \r
+ new Date(42), "yang-data-impl-groovyTest_", null);\r
+ } catch (URISyntaxException e) {\r
+ LOG.error(e.getMessage(), e);\r
+ }\r
+ return new MyNodeBuilder(qName);\r
+ }\r
+\r
+ @Override\r
+ protected void setParent(Object parent, Object child) {\r
+ // do nothing\r
+ if (child instanceof AbstractNodeTO<?>) {\r
+ ((AbstractNodeTO<?>) child).setParent((CompositeNode) parent);\r
+ } else {\r
+ LOG.error("PARENTING FAILED: "+parent + " -> " + child);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ protected Object createNode(Object name) {\r
+ MutableCompositeNode newNode = NodeFactory.createMutableCompositeNode(\r
+ createQName(name), getCurrentNode(), null, null, null);\r
+ NodeUtils.fixParentRelation(newNode);\r
+ return newNode;\r
+ }\r
+\r
+ @Override\r
+ protected Object createNode(Object name, @SuppressWarnings("rawtypes") Map attributes) {\r
+ ModifyAction modifyAction = processAttributes(attributes);\r
+ MutableCompositeNode newNode = NodeFactory.createMutableCompositeNode(\r
+ createQName(name), getCurrentNode(), null, modifyAction, null);\r
+ NodeUtils.fixParentRelation(newNode);\r
+ return newNode;\r
+ }\r
+\r
+\r
+ @Override\r
+ protected Object createNode(Object name, @SuppressWarnings("rawtypes") Map attributes, Object value) {\r
+ ModifyAction modifyAction = processAttributes(attributes);\r
+ SimpleNode<Object> newNode = NodeFactory.createImmutableSimpleNode(\r
+ createQName(name), (CompositeNode) getCurrent(), value, modifyAction);\r
+ NodeUtils.fixParentRelation(newNode);\r
+ return newNode;\r
+ }\r
+ \r
+ /**\r
+ * @param attributes\r
+ * @return \r
+ */\r
+ private ModifyAction processAttributes(@SuppressWarnings("rawtypes") Map attributes) {\r
+ LOG.debug("attributes:" + attributes);\r
+ ModifyAction modAction = null;\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ Map<String, String> attributesSane = attributes;\r
+ for (Entry<String, String> attr : attributesSane.entrySet()) {\r
+ switch (attr.getKey()) {\r
+ case "xmlns":\r
+ try {\r
+ qnNamespace = new URI(attr.getValue());\r
+ } catch (URISyntaxException e) {\r
+ LOG.error(e.getMessage(), e);\r
+ }\r
+ break;\r
+ case "modifyAction":\r
+ modAction = ModifyAction.valueOf(attr.getValue());\r
+ break;\r
+ \r
+ default:\r
+ throw new IllegalArgumentException("Attribute not supported: "+attr.getKey());\r
+ }\r
+ }\r
+ return modAction;\r
+ }\r
+\r
+ @Override\r
+ protected Object createNode(Object name, Object value) {\r
+ SimpleNode<Object> newNode = NodeFactory.createImmutableSimpleNode(createQName(name), (CompositeNode) getCurrent(), value);\r
+ NodeUtils.fixParentRelation(newNode);\r
+ return newNode;\r
+ }\r
+\r
+ private QName createQName(Object localName) {\r
+ LOG.debug("qname for: "+localName);\r
+ return new QName(qnNamespace, qnRevision, qnPrefix, (String) localName);\r
+ }\r
+\r
+ protected CompositeNode getCurrentNode() {\r
+ if (getCurrent() != null) {\r
+ if (getCurrent() instanceof CompositeNode) {\r
+ return (CompositeNode) getCurrent();\r
+ \r
+ } else {\r
+ throw new IllegalAccessError("current node is not of type CompositeNode, but: "\r
+ +getCurrent().getClass().getSimpleName());\r
+ }\r
+ }\r
+ \r
+ return null;\r
+ }\r
+ \r
+ @Override\r
+ protected Object postNodeCompletion(Object parent, Object node) {\r
+ Node<?> nodeRevisited = (Node<?>) node;\r
+ LOG.debug("postNodeCompletion at: \n "+ nodeRevisited+"\n "+parent);\r
+ if (nodeRevisited instanceof MutableCompositeNode) {\r
+ MutableCompositeNode mutant = (MutableCompositeNode) nodeRevisited;\r
+ if (mutant.getValue().isEmpty()) {\r
+ LOG.error("why is it having empty value? -- " + mutant);\r
+ }\r
+ nodeRevisited = NodeFactory.createImmutableCompositeNode(\r
+ mutant.getNodeType(), mutant.getParent(), mutant.getValue(), mutant.getModificationAction());\r
+ NodeUtils.fixChildrenRelation((CompositeNode) nodeRevisited);\r
+\r
+ if (parent == null) {\r
+ rootNode = (CompositeNode) nodeRevisited;\r
+ } else {\r
+ NodeUtils.fixParentRelation(nodeRevisited);\r
+ nodeRevisited.getParent().getChildren().remove(mutant);\r
+ }\r
+ }\r
+ \r
+ \r
+ return nodeRevisited;\r
+ }\r
+ \r
+ /**\r
+ * @return tree root\r
+ */\r
+ public CompositeNode getRootNode() {\r
+ return rootNode;\r
+ }\r
+}
\ No newline at end of file
*/\r
package org.opendaylight.controller.yang.data.impl;\r
\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.PrintStream;\r
import java.net.URI;\r
import java.util.ArrayList;\r
import java.util.Date;\r
import java.util.Map;\r
\r
import org.junit.Assert;\r
+import org.junit.Before;\r
import org.junit.Test;\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
import org.opendaylight.controller.yang.data.api.Node;\r
import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
import org.w3c.dom.Document;\r
\r
/**\r
* \r
*/\r
public class NodeFactoryTest {\r
+ \r
+ private QName qName;\r
+ private CompositeNode network;\r
+\r
+ private String ns;\r
+ private Document networkShadow;\r
+\r
+\r
+ /**\r
+ * @throws Exception\r
+ */\r
+ @Before\r
+ public void setUp() throws Exception {\r
+ ns = "urn:ietf:params:xml:ns:netconf:base:1.0";\r
+ qName = new QName(\r
+ new URI(ns), \r
+ new Date(42), null);\r
+ network = NodeHelper.buildTestConfigTree(qName);\r
+ networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ NodeHelper.compareXmlTree(networkShadow, "./config02-shadow.xml", getClass());\r
+ }\r
\r
/**\r
* Test method for methods creating immutable nodes in\r
*/\r
@Test\r
public void testImmutableNodes() throws Exception {\r
- QName qName = new QName(\r
- new URI("urn:opendaylight:controller:network"), \r
- new Date(42), "yang-data-impl-immutableTest_", null);\r
- \r
- CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
- \r
- \r
- Assert.assertEquals(1, network.getChildren().size());\r
- Document domTree = NodeUtils.buildShadowDomTree(network);\r
- NodeHelper.dumpDoc(domTree, System.out);\r
- \r
- CompositeNode tpList = NodeUtils.findNodeByXpath(domTree, \r
- "//node[node-id/text()='nodeId_19']/termination-points");\r
+ Assert.assertEquals(2, network.getChildren().size());\r
+ CompositeNode tpList = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id/text()='nodeId_19']/{0}termination-points", ns));\r
\r
\r
Assert.assertEquals(2, tpList.getCompositesByName("termination-point").size());\r
-// Assert.assertEquals(1, topologies.getCompositesByName("topology").size());\r
-// Assert.assertEquals(2, destination.getChildren().size());\r
}\r
\r
/**\r
- * Test method for methods creating immutable nodes in\r
- * {@link org.opendaylight.controller.yang.data.impl.NodeFactory}.\r
+ * Test method for methods creating immutable and mutable nodes:\r
+ * {@link NodeFactory#createMutableCompositeNode(QName, CompositeNode, List, ModifyAction, CompositeNode)},\r
+ * {@link NodeFactory#createMutableSimpleNode(QName, CompositeNode, Object, ModifyAction, SimpleNode)}\r
* @throws Exception \r
*/\r
@Test\r
// </top>\r
// </config>\r
\r
- QName qName = new QName(\r
- new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
- new Date(42), "yang-data-impl-mutableTest");\r
\r
List<Node<?>> value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet0/0"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1500));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "name"), null, "Ethernet0/0"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "mtu"), null, 1500));\r
\r
- CompositeNodeModificationTOImpl ifNode = NodeFactory.createCompositeNodeModification(\r
- new QName(qName, "interface"), null, value, ModifyAction.DELETE);\r
+ MutableCompositeNode ifNode = NodeFactory.createMutableCompositeNode(\r
+ new QName(qName, "interface"), null, value, ModifyAction.DELETE, null);\r
+ ifNode.init();\r
NodeHelper.assignParentToChildren(ifNode);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet1/0"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1501));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "name"), null, "Ethernet1/0"));\r
+ value.add(NodeFactory.createMutableSimpleNode(new QName(qName, "mtu"), null, 1501, ModifyAction.REMOVE, null));\r
\r
- CompositeNode ifNode2 = NodeFactory.createCompositeNode(new QName(qName, "interface"), null, value);\r
+ CompositeNode ifNode2 = NodeFactory.createImmutableCompositeNode(new QName(qName, "interface"), null, value);\r
NodeHelper.assignParentToChildren(ifNode2);\r
\r
value = new ArrayList<Node<?>>(); \r
value.add(ifNode);\r
value.add(ifNode2);\r
\r
- CompositeNode topNode = NodeFactory.createCompositeNode(new QName(qName, "top"), null, value);\r
+ CompositeNode topNode = NodeFactory.createImmutableCompositeNode(new QName(qName, "top"), null, value);\r
NodeHelper.assignParentToChildren(topNode);\r
value = new ArrayList<Node<?>>(); \r
value.add(topNode);\r
\r
- CompositeNode root = NodeFactory.createCompositeNode(new QName(qName, "config"), null, value);\r
- \r
+ CompositeNode root = NodeFactory.createImmutableCompositeNode(new QName(qName, "config"), null, value);\r
+ Document shadowConfig = NodeUtils.buildShadowDomTree(root);\r
+ NodeHelper.compareXmlTree(shadowConfig, "./mutableNodesConfig.xml", getClass());\r
\r
Assert.assertEquals(1, root.getChildren().size());\r
Assert.assertEquals(1, ifNode.getSimpleNodesByName("name").size());\r
Assert.assertEquals(1, ifNode.getSimpleNodesByName("mtu").size());\r
Assert.assertEquals(2, topNode.getCompositesByName("interface").size());\r
- NodeModification interfaceMod = (NodeModification) \r
- topNode.getCompositesByName("interface").get(0);\r
+ NodeModification interfaceMod = topNode.getCompositesByName("interface").get(0);\r
Assert.assertEquals(ModifyAction.DELETE, interfaceMod.getModificationAction());\r
}\r
\r
/**\r
- * test modifications builder\r
+ * test of {@link NodeFactory#copyDeepAsMutable(CompositeNode, Map)}\r
* @throws Exception \r
*/\r
@Test\r
- public void testCopyDeepNode() throws Exception {\r
- QName qName = new QName(\r
- new URI("urn:opendaylight:controller:network"), \r
- new Date(42), "yang-data-impl-immutableTest_", null);\r
- \r
- CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
+ public void testCopyDeepAsMutable() throws Exception {\r
Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
- MutableCompositeNode mutableNetwork = NodeFactory.copyDeepNode(network, mutableToOrig );\r
+ CompositeNode mutableNetwork = NodeFactory.copyDeepAsMutable(network, mutableToOrig);\r
\r
- Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
- ByteArrayOutputStream expected = new ByteArrayOutputStream();\r
- NodeHelper.dumpDoc(networkShadow, new PrintStream(expected));\r
- \r
Document mutableNetworkShadow = NodeUtils.buildShadowDomTree(mutableNetwork);\r
- ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
- NodeHelper.dumpDoc(mutableNetworkShadow, new PrintStream(actual));\r
\r
- Assert.assertEquals(new String(expected.toByteArray()), new String(actual.toByteArray()));\r
+ NodeHelper.compareXmlTree(mutableNetworkShadow, "./config02-shadow.xml", getClass());\r
+ \r
+ CompositeNode immutableNetwork = NodeFactory.copyDeepAsImmutable(mutableNetwork, null);\r
+ Assert.assertEquals(network, immutableNetwork);\r
+ }\r
+ \r
+ \r
+ /**\r
+ * test of {@link NodeFactory#copyDeepAsImmutable(CompositeNode, Map)}\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testCopyDeepAsImmutable() throws Exception {\r
+ Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
+ CompositeNode immutableNetwork = NodeFactory.copyDeepAsImmutable(network, mutableToOrig);\r
+ \r
+ Document mutableNetworkShadow = NodeUtils.buildShadowDomTree(immutableNetwork);\r
+ NodeHelper.compareXmlTree(mutableNetworkShadow, "./config02-shadow.xml", getClass());\r
+ \r
+ Assert.assertEquals(network, immutableNetwork);\r
}\r
\r
}\r
*/\r
package org.opendaylight.controller.yang.data.impl;\r
\r
+import groovy.lang.Binding;\r
+import groovy.lang.GroovyShell;\r
+import groovy.lang.Script;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
import java.io.PrintStream;\r
+import java.io.Reader;\r
import java.io.StringWriter;\r
+import java.lang.reflect.Method;\r
+import java.text.MessageFormat;\r
import java.util.ArrayList;\r
import java.util.List;\r
import java.util.Set;\r
import javax.xml.transform.dom.DOMSource;\r
import javax.xml.transform.stream.StreamResult;\r
\r
+import org.custommonkey.xmlunit.Diff;\r
+import org.junit.Assert;\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
import org.opendaylight.controller.yang.data.api.Node;\r
import org.opendaylight.controller.yang.model.api.SchemaContext;\r
import org.opendaylight.controller.yang.model.parser.api.YangModelParser;\r
import org.opendaylight.controller.yang.parser.impl.YangParserImpl;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
import org.w3c.dom.Document;\r
+import org.xml.sax.SAXException;\r
\r
/**\r
* @author michal.rehak\r
*/\r
public abstract class NodeHelper {\r
\r
+ private static final Logger LOG = LoggerFactory.getLogger(NodeHelper.class);\r
+ \r
/** xml source of example network configuration */\r
public static final String NETWORK_XML = \r
"<network xmlns=\"urn:opendaylight:controller:network\">\n" +\r
String xmlString = result.getWriter().toString();\r
out.println(xmlString);\r
}\r
-\r
+ \r
/**\r
* @param qName\r
* @return example tree, see {@link #NETWORK_XML}\r
*/\r
public static CompositeNode buildTestConfigTree(QName qName) {\r
List<Node<?>> value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
- CompositeNode ntElementNode1 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
+ CompositeNode ntElementNode1 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
assignParentToChildren(ntElementNode1);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
- CompositeNode ntElementNode2 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
+ CompositeNode ntElementNode2 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
assignParentToChildren(ntElementNode2);\r
\r
value = new ArrayList<Node<?>>();\r
value.add(ntElementNode1);\r
value.add(ntElementNode2);\r
- CompositeNode ntElementsNode = NodeFactory.createCompositeNode(\r
+ CompositeNode ntElementsNode = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "network-elements"), null, value);\r
assignParentToChildren(ntElementsNode);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
- CompositeNode destination = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
+ CompositeNode destination = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "destination"), null, value);\r
assignParentToChildren(destination);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
- CompositeNode source = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
+ CompositeNode source = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "source"), null, value);\r
assignParentToChildren(source);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
value.add(source);\r
value.add(destination);\r
- CompositeNode link1 = NodeFactory.createCompositeNode(\r
+ CompositeNode link1 = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "link"), null, value);\r
assignParentToChildren(link1);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
- destination = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
+ destination = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "destination"), null, value);\r
assignParentToChildren(destination);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
- source = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
+ source = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "source"), null, value);\r
assignParentToChildren(source);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
value.add(source);\r
value.add(destination);\r
- CompositeNode link2 = NodeFactory.createCompositeNode(\r
+ CompositeNode link2 = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "link"), null, value);\r
assignParentToChildren(link2);\r
\r
value = new ArrayList<Node<?>>(); \r
value.add(link1);\r
value.add(link2);\r
- CompositeNode links = NodeFactory.createCompositeNode(\r
+ CompositeNode links = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "links"), null, value);\r
assignParentToChildren(links);\r
\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
- CompositeNode terminationPointNode1 = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
+ CompositeNode terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "termination-point"), null, value);\r
assignParentToChildren(terminationPointNode1);\r
\r
value = new ArrayList<Node<?>>(); \r
value.add(terminationPointNode1);\r
- CompositeNode terminationPointsNode = NodeFactory.createCompositeNode(\r
+ CompositeNode terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "termination-points"), null, value);\r
assignParentToChildren(terminationPointsNode);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
value.add(terminationPointsNode);\r
- CompositeNode node1Node = NodeFactory.createCompositeNode(\r
+ CompositeNode node1Node = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "node"), null, value);\r
assignParentToChildren(node1Node);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
- terminationPointNode1 = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+ terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "termination-point"), null, value);\r
assignParentToChildren(terminationPointNode1);\r
\r
value = new ArrayList<Node<?>>(); \r
value.add(terminationPointNode1);\r
- terminationPointsNode = NodeFactory.createCompositeNode(\r
+ terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "termination-points"), null, value);\r
assignParentToChildren(terminationPointsNode);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
value.add(terminationPointsNode);\r
- CompositeNode node2Node = NodeFactory.createCompositeNode(\r
+ CompositeNode node2Node = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "node"), null, value);\r
assignParentToChildren(node2Node);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
- terminationPointNode1 = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+ terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "termination-point"), null, value);\r
assignParentToChildren(terminationPointNode1);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
- CompositeNode terminationPointNode2 = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
+ CompositeNode terminationPointNode2 = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "termination-point"), null, value);\r
assignParentToChildren(terminationPointNode2);\r
\r
value = new ArrayList<Node<?>>(); \r
value.add(terminationPointNode1);\r
value.add(terminationPointNode2);\r
- terminationPointsNode = NodeFactory.createCompositeNode(\r
+ terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "termination-points"), null, value);\r
assignParentToChildren(terminationPointsNode);\r
\r
value = new ArrayList<Node<?>>(); \r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
value.add(terminationPointsNode);\r
- CompositeNode node3Node = NodeFactory.createCompositeNode(\r
+ CompositeNode node3Node = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "node"), null, value);\r
assignParentToChildren(node3Node);\r
\r
value.add(node1Node);\r
value.add(node2Node);\r
value.add(node3Node);\r
- CompositeNode nodesNode = NodeFactory.createCompositeNode(\r
+ CompositeNode nodesNode = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "nodes"), null, value);\r
assignParentToChildren(nodesNode);\r
\r
value = new ArrayList<Node<?>>();\r
value.add(links);\r
value.add(nodesNode);\r
- value.add(NodeFactory.createSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
- CompositeNode topology = NodeFactory.createCompositeNode(\r
+ value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
+ CompositeNode topology = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "topology"), null, value);\r
assignParentToChildren(topology);\r
\r
value = new ArrayList<Node<?>>();\r
value.add(topology);\r
- CompositeNode topologies = NodeFactory.createCompositeNode(\r
+ CompositeNode topologies = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "topologies"), null, value);\r
assignParentToChildren(topologies);\r
\r
value = new ArrayList<Node<?>>();\r
value.add(topologies);\r
- CompositeNode network = NodeFactory.createCompositeNode(\r
+ value.add(ntElementsNode);\r
+ CompositeNode network = NodeFactory.createImmutableCompositeNode(\r
new QName(qName, "network"), null, value);\r
assignParentToChildren(network);\r
\r
.parseYangModelsFromStreams(yangInputStreams);\r
return yParser.resolveSchemaContext(modules);\r
}\r
+ \r
+ /**\r
+ * @param scriptName \r
+ * @return tree root\r
+ * @throws Exception\r
+ */\r
+ public static CompositeNode loadConfigByGroovy(String scriptName) throws Exception {\r
+ InputStream configStream = NodeHelper.class.getResourceAsStream(scriptName);\r
+ Binding binding = new Binding();\r
+ GroovyShell gShell = new GroovyShell(binding);\r
+ LOG.debug("groovy: starting script parse.. " + scriptName);\r
+ Script configScript = gShell.parse(new InputStreamReader(configStream));\r
+ LOG.debug("groovy: starting script.. " + scriptName);\r
+ configScript.run();\r
+ LOG.debug("groovy: digging result");\r
+ Object xmlGen = binding.getVariable("xmlGen");\r
+ LOG.debug("xmlGen = " + xmlGen);\r
+ Method getter = xmlGen.getClass().getDeclaredMethod("getBuilder", new Class[0]);\r
+ MyNodeBuilder builder = (MyNodeBuilder) getter.invoke(xmlGen, new Object[0]);\r
+ \r
+ return builder.getRootNode();\r
+ }\r
+ \r
+ /**\r
+ * @param pattern , e.g.: <pre>"//{0}:network/{1}:xx[text() = 'sss']"</pre>\r
+ * @param nsArg , e.g.: <pre>{"uri:ns1", "uri:ns2"}</pre>\r
+ * @return pattern with namespaces: <pre>//uri:ns1:network/uri:ns2:xx[text() = ''sss'']"</pre>\r
+ */\r
+ public static String AddNamespaceToPattern(String pattern, Object... nsArg) {\r
+ Object[] ns = nsArg;\r
+ String patternNs = pattern.replaceAll("'", "''");\r
+ if (ns == null) {\r
+ ns = new Object[]{""};\r
+ } else {\r
+ // add ':' into pattern after placeholders\r
+ patternNs = patternNs.replaceAll("(\\{[0-9]+\\})", "$1:");\r
+ }\r
+ \r
+ return MessageFormat.format(patternNs, ns);\r
+ }\r
+\r
+ /**\r
+ * @param tree\r
+ * @param xmlFile \r
+ * @param clazz \r
+ * @throws Exception\r
+ * @throws SAXException\r
+ * @throws IOException\r
+ */\r
+ public static void compareXmlTree(Document tree, String xmlFile, Class<?> clazz) throws Exception,\r
+ SAXException, IOException {\r
+ ByteArrayOutputStream actualRaw = new ByteArrayOutputStream();\r
+ dumpDoc(tree, new PrintStream(actualRaw));\r
+ Reader actualReader = new InputStreamReader(new ByteArrayInputStream(actualRaw.toByteArray()));\r
+ \r
+ Reader expectedReader = new InputStreamReader(clazz.getResourceAsStream(xmlFile));\r
+ Diff myDiff = new Diff(expectedReader, actualReader);\r
+ myDiff.overrideDifferenceListener(new IgnoreWhiteCharsDiffListener());\r
+ \r
+ boolean similar = myDiff.similar();\r
+ if (! similar) {\r
+ System.out.println(new String(actualRaw.toByteArray()));\r
+ }\r
+ Assert.assertEquals(myDiff.toString(), true, similar);\r
+ }\r
\r
}\r
import org.opendaylight.controller.yang.data.api.CompositeNode;\r
import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
import org.opendaylight.controller.yang.data.api.SimpleNode;\r
import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
import org.w3c.dom.Document;\r
\r
/**\r
* \r
*/\r
public class NodeModificationBuilderImplTest {\r
+ \r
+ private static final Logger LOG = LoggerFactory\r
+ .getLogger(NodeModificationBuilderImplTest.class);\r
\r
private SchemaContext schemaCtx;\r
private QName qName;\r
private CompositeNode network;\r
private NodeModificationBuilderImpl nodeModificationBuilder;\r
\r
+ private String ns;\r
+\r
+ /**\r
+ * @throws Exception\r
+ */\r
+ private void dumpResult() throws Exception {\r
+ CompositeNode diffTree = nodeModificationBuilder.buildDiffTree();\r
+ CompositeNode diffTreeImmutable = NodeFactory.copyDeepAsImmutable(diffTree, null);\r
+ \r
+ Document diffShadow = NodeUtils.buildShadowDomTree(diffTreeImmutable);\r
+ NodeHelper.dumpDoc(diffShadow, System.out);\r
+ }\r
+\r
/**\r
* prepare schemaContext\r
* @throws Exception \r
public void setUp() throws Exception {\r
schemaCtx = NodeHelper.loadSchemaContext();\r
\r
+ ns = "urn:opendaylight:controller:network";\r
qName = new QName(\r
- new URI("urn:opendaylight:controller:network"), \r
+ new URI(ns), \r
new Date(1369000800000L), "topos");\r
network = NodeHelper.buildTestConfigTree(qName);\r
\r
nodeModificationBuilder = new NodeModificationBuilderImpl(network, schemaCtx);\r
}\r
\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}\r
+ * .\r
+ */\r
+ @Test\r
+ public void testGetMutableEquivalent() {\r
+ MutableCompositeNode rootMutable = (MutableCompositeNode) \r
+ nodeModificationBuilder.getMutableEquivalent(network);\r
+ \r
+ CompositeNode topologies = network.getCompositesByName("topologies").iterator().next();\r
+ Node<?> mutableEquivalent = nodeModificationBuilder.getMutableEquivalent(topologies);\r
+ CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+ \r
+ Assert.assertSame(topologiesMutable, mutableEquivalent);\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTreeAddSimple() throws Exception {\r
+ LOG.debug("testBuildDiffTreeAddSimple");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ CompositeNode needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]", ns));\r
+ \r
+ MutableCompositeNode mutableParent = (MutableCompositeNode) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ MutableSimpleNode<String> newMutable = NodeFactory.createMutableSimpleNode(\r
+ new QName(needle.getNodeType(), "anySubNode"), mutableParent, "42", null, null);\r
+ \r
+ nodeModificationBuilder.addNode(newMutable);\r
+ dumpResult();\r
+ }\r
+ \r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTreeAddComposite() throws Exception {\r
+ LOG.debug("testBuildDiffTreeAddComposite");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ CompositeNode needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]", ns));\r
+ \r
+ MutableCompositeNode mutableParent = (MutableCompositeNode) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ MutableSimpleNode<String> newMutable = NodeFactory.createMutableSimpleNode(\r
+ new QName(needle.getNodeType(), "anySubNode"), null, "42", null, null);\r
+ \r
+ MutableCompositeNode newMutableCom = NodeFactory.createMutableCompositeNode(\r
+ new QName(needle.getNodeType(), "anySubNode"), mutableParent, \r
+ NodeUtils.buildChildrenList(newMutable), null, null);\r
+ NodeUtils.fixChildrenRelation(newMutableCom);\r
+ newMutableCom.init();\r
+ \r
+ nodeModificationBuilder.addNode(newMutableCom);\r
+ dumpResult();\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTreeDeleteComposite() throws Exception {\r
+ LOG.debug("testBuildDiffTreeDeleteComposite");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+\r
+ @SuppressWarnings("unchecked")\r
+ MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ nodeModificationBuilder.deleteNode(mutableNeedle.getParent().asMutable());\r
+ dumpResult();\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTreeDeleteSimple() throws Exception {\r
+ LOG.debug("testBuildDiffTreeDeleteSimple");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ nodeModificationBuilder.deleteNode(mutableNeedle);\r
+ dumpResult();\r
+ }\r
+\r
/**\r
* Test method for\r
* {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
* @throws Exception \r
*/\r
@Test\r
- public void testBuildDiffTree() throws Exception {\r
+ public void testBuildDiffTreeMerge() throws Exception {\r
+ LOG.debug("testBuildDiffTreeMerge");\r
Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
- SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
- "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\r
+ SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
\r
@SuppressWarnings("unchecked")\r
MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
nodeModificationBuilder.getMutableEquivalent(needle);\r
\r
mutableNeedle.setValue("tpId_18x");\r
- nodeModificationBuilder.replaceNode(mutableNeedle);\r
- CompositeNode diffTree = nodeModificationBuilder.buildDiffTree();\r
+ nodeModificationBuilder.mergeNode(mutableNeedle.getParent().asMutable());\r
+ dumpResult();\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTreeRemoveComposite() throws Exception {\r
+ LOG.debug("testBuildDiffTreeRemoveComposite");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
\r
- Document diffShadow = NodeUtils.buildShadowDomTree(diffTree);\r
- NodeHelper.dumpDoc(diffShadow, System.out);\r
+ @SuppressWarnings("unchecked")\r
+ MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ nodeModificationBuilder.removeNode(mutableNeedle.getParent().asMutable());\r
+ dumpResult();\r
}\r
\r
/**\r
* Test method for\r
- * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
* .\r
+ * @throws Exception \r
*/\r
@Test\r
- public void testGetMutableEquivalent() {\r
- MutableCompositeNode rootMutable = (MutableCompositeNode) \r
- nodeModificationBuilder.getMutableEquivalent(network);\r
+ public void testBuildDiffTreeRemoveSimple() throws Exception {\r
+ LOG.debug("testBuildDiffTreeRemoveSimple");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
\r
- CompositeNode topologies = network.getCompositesByName("topologies").iterator().next();\r
- CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+ @SuppressWarnings("unchecked")\r
+ MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ nodeModificationBuilder.removeNode(mutableNeedle);\r
+ dumpResult();\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTreeReplaceComposite() throws Exception {\r
+ LOG.debug("testBuildDiffTreeReplaceComposite");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ mutableNeedle.setValue("tpId_18x");\r
+ nodeModificationBuilder.replaceNode(mutableNeedle.getParent().asMutable());\r
+ dumpResult();\r
+ }\r
+\r
+ /**\r
+ * Test method for\r
+ * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+ * .\r
+ * @throws Exception \r
+ */\r
+ @Test\r
+ public void testBuildDiffTreeReplaceSimple() throws Exception {\r
+ LOG.debug("testBuildDiffTreeReplaceSimple");\r
+ Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
\r
- Assert.assertSame(topologiesMutable, nodeModificationBuilder.getMutableEquivalent(topologies));\r
+ @SuppressWarnings("unchecked")\r
+ MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+ nodeModificationBuilder.getMutableEquivalent(needle);\r
+ \r
+ mutableNeedle.setValue("tpId_18x");\r
+ nodeModificationBuilder.replaceNode(mutableNeedle);\r
+ dumpResult();\r
}\r
\r
+\r
}\r
*/\r
package org.opendaylight.controller.yang.data.impl;\r
\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.PrintStream;\r
+import java.io.IOException;\r
import java.net.URI;\r
import java.util.Date;\r
import java.util.List;\r
import java.util.Map;\r
+import java.util.Stack;\r
\r
import org.junit.Assert;\r
import org.junit.Before;\r
import org.opendaylight.controller.yang.data.api.SimpleNode;\r
import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
import org.w3c.dom.Document;\r
\r
/**\r
*/\r
public class NodeUtilsTest {\r
\r
+ private static final Logger LOG = LoggerFactory\r
+ .getLogger(NodeUtilsTest.class);\r
+ \r
private QName qName;\r
private CompositeNode network;\r
\r
+ private String ns;\r
+\r
+\r
/**\r
* @throws Exception\r
*/\r
@Before\r
public void setUp() throws Exception {\r
+ ns = "urn:ietf:params:xml:ns:netconf:base:1.0";\r
qName = new QName(\r
- new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
+ new URI(ns), \r
new Date(42), "yang-data-impl-mutableTest");\r
network = NodeHelper.buildTestConfigTree(qName);\r
}\r
*/\r
@Test\r
public void testBuildShadowDomTree() throws Exception {\r
+ MemoryConsumption mc = new MemoryConsumption();\r
+ mc.startObserving();\r
+ \r
Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
- ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
- NodeHelper.dumpDoc(networkShadow, new PrintStream(actual));\r
\r
- Assert.assertEquals(2760, new String(actual.toByteArray()).length());\r
+ LOG.debug("After dom built: "+mc.finishObserving());\r
+ NodeHelper.compareXmlTree(networkShadow, "./config02-shadow.xml", getClass());\r
}\r
\r
/**\r
@Test\r
public void testFindNodeByXpath() throws Exception {\r
Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+ MemoryConsumption mc = new MemoryConsumption();\r
+ mc.startObserving();\r
+ \r
SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
- "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\r
+ NodeHelper.AddNamespaceToPattern(\r
+ "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+ \r
+ LOG.debug("After xpath executed: "+mc.finishObserving());\r
+ \r
Assert.assertNotNull(needle);\r
Assert.assertEquals("tpId_18", needle.getValue());\r
}\r
-\r
+ \r
/**\r
* Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildNodeMap(java.util.List)}.\r
*/\r
Assert.assertEquals(5, mapOfLists.size());\r
}\r
\r
+ /**\r
+ * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}.\r
+ * @throws Exception \r
+ * @throws IOException \r
+ */\r
+ @Test\r
+ public void testLoadConfigByGroovy() throws IOException, Exception {\r
+ CompositeNode treeRoot = NodeHelper.loadConfigByGroovy("./config02.groovy");\r
+ Document shadowTree = NodeUtils.buildShadowDomTree(treeRoot);\r
+ try {\r
+ checkFamilyBinding(treeRoot);\r
+ } catch (Exception e) {\r
+ LOG.error(e.getMessage());\r
+ throw e;\r
+ }\r
+ \r
+ NodeHelper.compareXmlTree(shadowTree, "./config02g-shadow.xml", getClass());\r
+ }\r
+\r
+ private static void checkFamilyBinding(CompositeNode treeRoot) throws Exception {\r
+ Stack<CompositeNode> jobQueue = new Stack<>();\r
+ jobQueue.push(treeRoot);\r
+ \r
+ while (!jobQueue.isEmpty()) {\r
+ CompositeNode job = jobQueue.pop();\r
+ for (Node<?> child : job.getChildren()) {\r
+ if (child instanceof CompositeNode) {\r
+ jobQueue.push((CompositeNode) child);\r
+ }\r
+ \r
+ if (job != child.getParent()) {\r
+ throw new Exception("binding mismatch occured: \nPARENT["+job+"]\n CHILD[" + child+"]\n +-> "+child.getParent());\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
}\r
--- /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
+ */
+import groovy.xml.MarkupBuilder
+import org.opendaylight.controller.yang.data.impl.MyNodeBuilder
+
+/**
+ * wrapper class - applies hardcoded builder on given data closure
+ */
+class MyXmlGenerator {
+
+ def myBuilder
+
+ MyXmlGenerator() {
+ myBuilder = MyNodeBuilder.newInstance();
+ }
+
+ MyNodeBuilder getBuilder() {
+ return myBuilder;
+ }
+
+ void buildTree(data) {
+ data.setDelegate(myBuilder)
+ data()
+ }
+
+ /**
+ * tests builder execution
+ */
+ static void main(args) {
+ println 'hello'
+ def data = {
+ network(xmlns: 'urn:opendaylight:controller:network') {
+ topologies {
+ topology {
+ 'topology-id'('topId_01')
+
+ nodes {
+ node {
+ 'node-id'('nodeId_02')
+ 'supporting-ne'('networkId_03')
+ 'termination-points' {
+ 'termination-point' {
+ 'tp-id'('tpId_04')
+ }
+ }
+ }
+ node {
+ 'node-id'('nodeId_05')
+ 'supporting-ne'('networkId_06')
+ 'termination-points' {
+ 'termination-point' {
+ 'tp-id'('tpId_07')
+ }
+ }
+ }
+ node {
+ 'node-id'('nodeId_08')
+ 'supporting-ne'('networkId_09')
+ 'termination-points' {
+ 'termination-point' {
+ 'tp-id'('tpId_10')
+ }
+ 'termination-point' {
+ 'tp-id'('tpId_11')
+ }
+ }
+ }
+ }
+ links {
+ link {
+ 'link-id'('linkId_12')
+ source {
+ 'source-node'('nodeId_13')
+ 'source-tp'('tpId_13')
+ }
+ destination {
+ 'dest-node'('nodeId_14')
+ 'dest-tp'('tpId_14')
+ }
+ }
+ link {
+ 'link-id'('linkId_15')
+ source {
+ 'source-node'('nodeId_16')
+ 'source-tp'('tpId_16')
+ }
+ destination {
+ 'dest-node'('nodeId_17')
+ 'dest-tp'('tpId_17')
+ }
+ }
+ }
+ }
+ }
+ 'network-elements' {
+ 'network-element' {
+ 'element-id'('ntElementId_18')
+ }
+ 'network-element' {
+ 'element-id'('ntElementId_19')
+ }
+ }
+ }
+
+ }
+
+ def xmlGen = new MyXmlGenerator()
+ xmlGen.buildTree(data)
+ println xmlGen.getBuilder().getRootNode()
+ }
+
+}
+
+
+
+++ /dev/null
-xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {\r
- topologies {\r
- topology {\r
- 'topology-id'('topId_'+cnt.get())\r
- \r
- types()\r
- nodes {\r
- node {\r
- 'node-id'('nodeId_'+cnt.get())\r
- 'supporting-ne'('networkId_'+cnt.get())\r
- 'termination-points' {\r
- 'termination-point' {\r
- 'tp-id'('tpId_'+cnt.get())\r
- }\r
- }\r
- }\r
- node {\r
- 'node-id'('nodeId_'+cnt.get())\r
- 'supporting-ne'('networkId_'+cnt.get())\r
- 'termination-points' {\r
- 'termination-point' {\r
- 'tp-id'('tpId_'+cnt.get())\r
- }\r
- }\r
- }\r
- node {\r
- 'node-id'('nodeId_'+cnt.get())\r
- 'supporting-ne'('networkId_'+cnt.get())\r
- 'termination-points' {\r
- 'termination-point' {\r
- 'tp-id'('tpId_'+cnt.get())\r
- }\r
- 'termination-point' {\r
- 'tp-id'('tpId_'+cnt.get())\r
- }\r
- }\r
- }\r
- }\r
- links {\r
- link {\r
- 'link-id'('linkId_'+cnt.get())\r
- source {\r
- 'source-node'('nodeId_'+cnt.get())\r
- 'source-tp'('tpId_'+cnt.get(false))\r
- }\r
- destination {\r
- 'dest-node'('nodeId_'+cnt.get())\r
- 'dest-tp'('tpId_'+cnt.get(false))\r
- }\r
- }\r
- link {\r
- 'link-id'('linkId_'+cnt.get())\r
- source {\r
- 'source-node'('nodeId_'+cnt.get())\r
- 'source-tp'('tpId_'+cnt.get(false))\r
- }\r
- destination {\r
- 'dest-node'('nodeId_'+cnt.get())\r
- 'dest-tp'('tpId_'+cnt.get(false))\r
- }\r
- }\r
- }\r
- }\r
- }\r
- 'network-elements' {\r
- 'network-element' {\r
- 'element-id'('ntElementId_'+cnt.get())\r
- }\r
- 'network-element' {\r
- 'element-id'('ntElementId_'+cnt.get())\r
- }\r
- }\r
- }
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<network xmlns="urn:opendaylight:controller:network">
- <topologies>
- <topology>
- <topology-id>topId_01</topology-id>
- <types />
- <nodes>
- <node>
- <node-id>nodeId_02</node-id>
- <supporting-ne>networkId_03</supporting-ne>
- <termination-points>
- <termination-point>
- <tp-id>tpId_04</tp-id>
- </termination-point>
- </termination-points>
- </node>
- <node>
- <node-id>nodeId_05</node-id>
- <supporting-ne>networkId_06</supporting-ne>
- <termination-points>
- <termination-point>
- <tp-id>tpId_07</tp-id>
- </termination-point>
- </termination-points>
- </node>
- <node>
- <node-id>nodeId_08</node-id>
- <supporting-ne>networkId_09</supporting-ne>
- <termination-points>
- <termination-point>
- <tp-id>tpId_10</tp-id>
- </termination-point>
- <termination-point>
- <tp-id>tpId_11</tp-id>
- </termination-point>
- </termination-points>
- </node>
- </nodes>
- <links>
- <link>
- <link-id>linkId_12</link-id>
- <source>
- <source-node>nodeId_13</source-node>
- <source-tp>tpId_13</source-tp>
- </source>
- <destination>
- <dest-node>nodeId_14</dest-node>
- <dest-tp>tpId_14</dest-tp>
- </destination>
- </link>
- <link>
- <link-id>linkId_15</link-id>
- <source>
- <source-node>nodeId_16</source-node>
- <source-tp>tpId_16</source-tp>
- </source>
- <destination>
- <dest-node>nodeId_17</dest-node>
- <dest-tp>tpId_17</dest-tp>
- </destination>
- </link>
- </links>
- </topology>
- </topologies>
- <network-elements>
- <network-element>
- <element-id>ntElementId_18</element-id>
- </network-element>
- <network-element>
- <element-id>ntElementId_19</element-id>
- </network-element>
- </network-elements>
-</network>\r
+++ /dev/null
-//import groovy.xml.StreamingMarkupBuilder
-import groovy.xml.MarkupBuilder
-import groovy.xml.XmlUtil
-
-class Counter {
- def counter = 0
- def get() {
- return get(true)
- }
- def get(isInc) {
- if (isInc) {
- counter++
- }
- return String.format('%02d', counter)
- }
-}
-
-
-cnt = new Counter()
-def writer = new StringWriter()
-xmlDoc = new MarkupBuilder(writer)
-xmlDoc.setDoubleQuotes(true)
-xmlDoc.getMkp().xmlDeclaration(version:'1.0', encoding: 'UTF-8')
-
-//def data = {
-// mkp.xmlDeclaration()
-// network(xmlns: 'urn:opendaylight:controller:network') {
-dataFile = new File(args[0])
-evaluate(dataFile)
-// xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {
- // topologies {
- // topology {
- // 'topology-id'('topId_'+cnt.get())
- // types()
- // nodes {
- // node {
- // 'node-id'('nodeId_'+cnt.get())
- // 'supporting-ne'('networkId_'+cnt.get())
- // 'termination-points' {
- // 'termination-point' {
- // 'tp-id'('tpId_'+cnt.get())
- // }
- // }
- // }
- // node {
- // 'node-id'('nodeId_'+cnt.get())
- // 'supporting-ne'('networkId_'+cnt.get())
- // 'termination-points' {
- // 'termination-point' {
- // 'tp-id'('tpId_'+cnt.get())
- // }
- // }
- // }
- // node {
- // 'node-id'('nodeId_'+cnt.get())
- // 'supporting-ne'('networkId_'+cnt.get())
- // 'termination-points' {
- // 'termination-point' {
- // 'tp-id'('tpId_'+cnt.get())
- // }
- // 'termination-point' {
- // 'tp-id'('tpId_'+cnt.get())
- // }
- // }
- // }
- // }
- // links {
- // link {
- // 'link-id'('linkId_'+cnt.get())
- // source {
- // 'source-node'('nodeId_'+cnt.get())
- // 'source-tp'('tpId_'+cnt.get(false))
- // }
- // destination {
- // 'dest-node'('nodeId_'+cnt.get())
- // 'dest-tp'('tpId_'+cnt.get(false))
- // }
- // }
- // link {
- // 'link-id'('linkId_'+cnt.get())
- // source {
- // 'source-node'('nodeId_'+cnt.get())
- // 'source-tp'('tpId_'+cnt.get(false))
- // }
- // destination {
- // 'dest-node'('nodeId_'+cnt.get())
- // 'dest-tp'('tpId_'+cnt.get(false))
- // }
- // }
- // }
- // }
- // }
- // 'network-elements' {
- // 'network-element' {
- // 'element-id'('ntElementId_'+cnt.get())
- // }
- // 'network-element' {
- // 'element-id'('ntElementId_'+cnt.get())
- // }
- // }
- // }
-
-//}
-
-
-// def xmlDoc = new StreamingMarkupBuilder()
-// xmlDoc.encoding = 'UTF'
-//println XmlUtil.serialize(xmlDoc.bind(data))
-
-println writer
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">\r
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">\r
+\r
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">\r
+ <layout class="org.apache.log4j.PatternLayout">\r
+ <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%t] %42.42c %x - %m%n"/>\r
+ </layout>\r
+ </appender> \r
+\r
+ <logger name="org.opendaylight.controller.yang.data.impl" additivity="false">\r
+ <level value="DEBUG" />\r
+ <appender-ref ref="console"/>\r
+ </logger>\r
+ <logger name="org.opendaylight.controller.yang.data.impl.MyNodeBuilder" additivity="false">\r
+ <level value="INFO" />\r
+ <appender-ref ref="console"/>\r
+ </logger> \r
+ \r
+ <root>\r
+ <priority value="INFO"/>\r
+ <appender-ref ref="console" />\r
+ </root>\r
+</log4j:configuration>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<network xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <topologies>
+ <topology>
+ <topology-id>topId_01</topology-id>
+ <nodes>
+ <node>
+ <node-id>nodeId_19</node-id>
+ <supporting-ne>networkId_20</supporting-ne>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_19</tp-id>
+ </termination-point>
+ <termination-point>
+ <tp-id>tpId_18</tp-id>
+ </termination-point>
+ </termination-points>
+ </node>
+ <node>
+ <node-id>nodeId_16</node-id>
+ <supporting-ne>networkId_17</supporting-ne>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_18</tp-id>
+ </termination-point>
+ </termination-points>
+ </node>
+ <node>
+ <node-id>nodeId_02</node-id>
+ <supporting-ne>networkId_02</supporting-ne>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_03</tp-id>
+ </termination-point>
+ </termination-points>
+ </node>
+ </nodes>
+ <links>
+ <link>
+ <destination>
+ <dest-tp>tpId_15</dest-tp>
+ <dest-node>nodeId_14</dest-node>
+ </destination>
+ <source>
+ <source-tp>tpId_13</source-tp>
+ <source-node>nodeId_12</source-node>
+ </source>
+ <link-id>linkId_11</link-id>
+ </link>
+ <link>
+ <destination>
+ <dest-tp>tpId_08</dest-tp>
+ <dest-node>nodeId_07</dest-node>
+ </destination>
+ <source>
+ <source-tp>tpId_06</source-tp>
+ <source-node>nodeId_05</source-node>
+ </source>
+ <link-id>linkId_04</link-id>
+ </link>
+ </links>
+ </topology>
+ </topologies>
+ <network-elements>
+ <network-element>
+ <element-id>ntElementId_10</element-id>
+ </network-element>
+ <network-element>
+ <element-id>ntElementId_09</element-id>
+ </network-element>
+ </network-elements>
+</network>
--- /dev/null
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+def data = {\r
+ network(xmlns: 'urn:opendaylight:controller:network') {\r
+ topologies {\r
+ topology {\r
+ 'topology-id'('topId_01')\r
+ \r
+ //types()\r
+ nodes {\r
+ node {\r
+ 'node-id'('nodeId_02')\r
+ 'supporting-ne'('networkId_03')\r
+ 'termination-points' {\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_04')\r
+ }\r
+ }\r
+ }\r
+ node {\r
+ 'node-id'('nodeId_05')\r
+ 'supporting-ne'('networkId_06')\r
+ 'termination-points' {\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_07')\r
+ }\r
+ }\r
+ }\r
+ node {\r
+ 'node-id'('nodeId_08')\r
+ 'supporting-ne'('networkId_09')\r
+ 'termination-points' {\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_10')\r
+ }\r
+ 'termination-point' {\r
+ 'tp-id'('tpId_11')\r
+ }\r
+ }\r
+ }\r
+ }\r
+ links {\r
+ link {\r
+ 'link-id'('linkId_12')\r
+ source {\r
+ 'source-node'('nodeId_13')\r
+ 'source-tp'('tpId_13')\r
+ }\r
+ destination {\r
+ 'dest-node'('nodeId_14')\r
+ 'dest-tp'('tpId_14')\r
+ }\r
+ }\r
+ link {\r
+ 'link-id'('linkId_15')\r
+ source {\r
+ 'source-node'('nodeId_16')\r
+ 'source-tp'('tpId_16')\r
+ }\r
+ destination {\r
+ 'dest-node'('nodeId_17')\r
+ 'dest-tp'('tpId_17')\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ 'network-elements' {\r
+ 'network-element' {\r
+ 'element-id'('ntElementId_18')\r
+ }\r
+ 'network-element' {\r
+ 'element-id'('ntElementId_19')\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+System.err.println('data inited')\r
+\r
+import MyXmlGenerator\r
+\r
+xmlGen = new MyXmlGenerator()\r
+xmlGen.buildTree(data)\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<network xmlns="urn:opendaylight:controller:network">
+ <topologies>
+ <topology>
+ <links>
+ <link>
+ <destination>
+ <dest-tp>tpId_17</dest-tp>
+ <dest-node>nodeId_17</dest-node>
+ </destination>
+ <source>
+ <source-tp>tpId_16</source-tp>
+ <source-node>nodeId_16</source-node>
+ </source>
+ <link-id>linkId_15</link-id>
+ </link>
+ <link>
+ <destination>
+ <dest-tp>tpId_14</dest-tp>
+ <dest-node>nodeId_14</dest-node>
+ </destination>
+ <source>
+ <source-tp>tpId_13</source-tp>
+ <source-node>nodeId_13</source-node>
+ </source>
+ <link-id>linkId_12</link-id>
+ </link>
+ </links>
+ <nodes>
+ <node>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_11</tp-id>
+ </termination-point>
+ <termination-point>
+ <tp-id>tpId_10</tp-id>
+ </termination-point>
+ </termination-points>
+ <supporting-ne>networkId_09</supporting-ne>
+ <node-id>nodeId_08</node-id>
+ </node>
+ <node>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_07</tp-id>
+ </termination-point>
+ </termination-points>
+ <supporting-ne>networkId_06</supporting-ne>
+ <node-id>nodeId_05</node-id>
+ </node>
+ <node>
+ <termination-points>
+ <termination-point>
+ <tp-id>tpId_04</tp-id>
+ </termination-point>
+ </termination-points>
+ <supporting-ne>networkId_03</supporting-ne>
+ <node-id>nodeId_02</node-id>
+ </node>
+ </nodes>
+ <topology-id>topId_01</topology-id>
+ </topology>
+ </topologies>
+ <network-elements>
+ <network-element>
+ <element-id>ntElementId_19</element-id>
+ </network-element>
+ <network-element>
+ <element-id>ntElementId_18</element-id>
+ </network-element>
+ </network-elements>
+</network>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <top>
+ <interface>
+ <mtu modifyAction="REMOVE">1501</mtu>
+ <name>Ethernet1/0</name>
+ </interface>
+ <interface modifyAction="DELETE">
+ <mtu>1500</mtu>
+ <name>Ethernet0/0</name>
+ </interface>
+ </top>
+</config>
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
- <modelVersion>4.0.0</modelVersion>\r
+\r
<parent>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang</artifactId>\r
<version>0.5.4-SNAPSHOT</version>\r
</parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
<artifactId>yang-data-util</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>${project.artifactId}</description>\r
+\r
<dependencies>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang-data-api</artifactId>\r
</dependency>\r
</dependencies>\r
-</project>
\ No newline at end of file
+\r
+</project>\r
import org.opendaylight.controller.yang.common.QName;
import org.opendaylight.controller.yang.data.api.CompositeNode;
+import org.opendaylight.controller.yang.data.api.ModifyAction;
import org.opendaylight.controller.yang.data.api.Node;
public abstract class AbstractNode<T> implements Node<T> {
public CompositeNode getParent() {
return parent;
}
+
+ /* (non-Javadoc)
+ */
+ /**
+ * @see org.opendaylight.controller.yang.data.api.NodeModification#getModificationAction()
+ */
+ public ModifyAction getModificationAction() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
import org.opendaylight.controller.yang.common.QName;
import org.opendaylight.controller.yang.data.api.CompositeNode;
+import org.opendaylight.controller.yang.data.api.ModifyAction;
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;
import org.opendaylight.controller.yang.data.api.Node;
import org.opendaylight.controller.yang.data.api.SimpleNode;
return nodeMap;
}
+
+ /* (non-Javadoc)
+ * @see org.opendaylight.controller.yang.data.api.CompositeNode#asMutable()
+ */
+ @Override
+ public MutableCompositeNode asMutable() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
private static class SimpleNodeTO<T> extends AbstractNode<T> implements
return value;
}
+ /* (non-Javadoc)
+ * @see org.opendaylight.controller.yang.data.api.SimpleNode#asMutable()
+ */
+ @Override
+ public MutableSimpleNode<T> asMutable() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
}
<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>yang</artifactId>
<version>0.5.4-SNAPSHOT</version>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>yang-ext</artifactId>
<version>2013.09.07-SNAPSHOT</version>
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
<build>
<plugins>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
- <modelVersion>4.0.0</modelVersion>\r
+\r
<parent>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang</artifactId>\r
<version>0.5.4-SNAPSHOT</version>\r
</parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
<artifactId>yang-model-api</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>${project.artifactId}</description>\r
+\r
<dependencies>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang-common</artifactId>\r
</dependency>\r
</dependencies>\r
+\r
</project>\r
import org.opendaylight.controller.yang.model.api.TypeDefinition;
-public interface DecimalTypeDefinition extends
- TypeDefinition<DecimalTypeDefinition> {
+public interface DecimalTypeDefinition extends TypeDefinition<DecimalTypeDefinition> {
List<RangeConstraint> getRangeStatements();
/**
* Returns integer between 1 and 18 inclusively. <br>
* <br>
- *
+ *
* The "fraction-digits" statement controls the size of the minimum
* difference between values of a decimal64 type, by restricting the value
* space to numbers that are expressible as "i x 10^-n" where n is the
* fraction-digits argument.
- *
- * @return
+ *
+ * @return number of fraction digits
*/
Integer getFractionDigits();
}
<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>yang</artifactId>
<version>0.5.4-SNAPSHOT</version>
- <relativePath>../../yang/pom.xml</relativePath>
</parent>
+
+ <modelVersion>4.0.0</modelVersion>
<artifactId>yang-model-parser-api</artifactId>
+ <name>${project.artifactId}</name>
+ <description>YANG parser API</description>
+
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-model-api</artifactId>
</dependency>
</dependencies>
+
</project>
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>yang</artifactId>\r
<version>0.5.4-SNAPSHOT</version>\r
- <relativePath>../../yang/pom.xml</relativePath>\r
</parent>\r
\r
<modelVersion>4.0.0</modelVersion>\r
<artifactId>yang-model-parser-impl</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>YANG parser</description>\r
\r
<dependencies>\r
<dependency>\r
</execution>\r
</executions>\r
</plugin>\r
+ <plugin>\r
+ <groupId>org.apache.maven.plugins</groupId>\r
+ <artifactId>maven-javadoc-plugin</artifactId>\r
+ <configuration>\r
+ <excludePackageNames>\r
+ *.opendaylight.controller.antlrv4.code.gen\r
+ </excludePackageNames>\r
+ </configuration>\r
+ </plugin>\r
</plugins>\r
<pluginManagement>\r
<plugins>\r
import java.util.ArrayList;
import java.util.List;
-import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.model.api.TypeDefinition;
import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
/**
- * Basic implementation for TypeAwareBuilder builders.
+ * Basic implementation of Builder.
*/
-public abstract class AbstractTypeAwareBuilder implements TypeAwareBuilder {
+public abstract class AbstractBuilder implements Builder {
+ protected String moduleName;
protected final int line;
- protected final QName qname;
protected Builder parent;
- protected TypeDefinition<?> type;
- protected TypeDefinitionBuilder typedef;
+
protected List<UnknownSchemaNode> unknownNodes;
protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
- public AbstractTypeAwareBuilder(final int line, final QName qname) {
+ protected AbstractBuilder(final String moduleName, final int line) {
+ this.moduleName = moduleName;
this.line = line;
- this.qname = qname;
- }
-
- @Override
- public int getLine() {
- return line;
- }
-
- @Override
- public Builder getParent() {
- return parent;
}
@Override
- public void setParent(final Builder parent) {
- this.parent = parent;
- }
-
- @Override
- public QName getQName() {
- return qname;
+ public String getModuleName() {
+ return moduleName;
}
@Override
- public TypeDefinition<?> getType() {
- return type;
+ public void setModuleName(final String moduleName) {
+ this.moduleName = moduleName;
}
@Override
- public TypeDefinitionBuilder getTypedef() {
- return typedef;
+ public int getLine() {
+ return line;
}
@Override
- public void setType(TypeDefinition<?> type) {
- this.type = type;
- this.typedef = null;
+ public Builder getParent() {
+ return parent;
}
@Override
- public void setTypedef(TypeDefinitionBuilder typedef) {
- this.typedef = typedef;
- this.type = null;
+ public void setParent(final Builder parent) {
+ this.parent = parent;
}
@Override
*/
package org.opendaylight.controller.yang.parser.builder.api;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import org.opendaylight.controller.yang.common.QName;
import org.opendaylight.controller.yang.model.api.DataSchemaNode;
import org.opendaylight.controller.yang.model.api.GroupingDefinition;
-import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
import org.opendaylight.controller.yang.parser.util.YangParseException;
/**
* Basic implementation of DataNodeContainerBuilder.
*/
-public abstract class AbstractDataNodeContainerBuilder implements DataNodeContainerBuilder {
- protected final int line;
+public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder implements DataNodeContainerBuilder {
protected final QName qname;
- protected Builder parent;
protected Set<DataSchemaNode> childNodes;
protected final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<DataSchemaNodeBuilder>();
protected Set<GroupingDefinition> groupings;
protected final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
- protected List<UnknownSchemaNode> unknownNodes;
- protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
-
- protected AbstractDataNodeContainerBuilder(final int line, final QName qname) {
- this.line = line;
+ protected AbstractDataNodeContainerBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line);
this.qname = qname;
}
- @Override
- public int getLine() {
- return line;
- }
-
- @Override
- public Builder getParent() {
- return parent;
- }
-
- @Override
- public void setParent(final Builder parent) {
- this.parent = parent;
- }
-
@Override
public QName getQName() {
return qname;
@Override
public void addChildNode(DataSchemaNodeBuilder child) {
- for (DataSchemaNodeBuilder childNode : addedChildNodes) {
- if (childNode.getQName().getLocalName().equals(child.getQName().getLocalName())) {
- throw new YangParseException(child.getLine(), "Duplicate node found at line " + childNode.getLine());
+ String childName = child.getQName().getLocalName();
+ for (DataSchemaNodeBuilder addedChildNode : addedChildNodes) {
+ if (addedChildNode.getQName().getLocalName().equals(childName)) {
+ throw new YangParseException(child.getModuleName(), child.getLine(), "Can not add '" + child + "' to '"
+ + this + "' in module '" + moduleName + "': node with same name already declared at line "
+ + addedChildNode.getLine());
}
}
addedChildNodes.add(child);
}
@Override
- public void addGrouping(GroupingBuilder groupingBuilder) {
- for (GroupingBuilder gb : addedGroupings) {
- if (gb.getQName().getLocalName().equals(groupingBuilder.getQName().getLocalName())) {
- throw new YangParseException(groupingBuilder.getLine(), "Duplicate node found at line " + gb.getLine());
+ public void addGrouping(GroupingBuilder grouping) {
+ String groupingName = grouping.getQName().getLocalName();
+ for (GroupingBuilder addedGrouping : addedGroupings) {
+ if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
+ throw new YangParseException(grouping.getModuleName(), grouping.getLine(), "Can not add '" + grouping
+ + "': grouping with same name already declared in module '" + moduleName + "' at line "
+ + addedGrouping.getLine());
}
}
- addedGroupings.add(groupingBuilder);
- }
-
- @Override
- public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
- return addedUnknownNodes;
- }
-
- @Override
- public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
- addedUnknownNodes.add(unknownNode);
- }
-
- public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
- this.unknownNodes = unknownNodes;
+ addedGroupings.add(grouping);
}
}
*/\r
package org.opendaylight.controller.yang.parser.builder.api;\r
\r
-import java.util.ArrayList;\r
import java.util.List;\r
\r
import org.opendaylight.controller.yang.common.QName;\r
import org.opendaylight.controller.yang.model.api.SchemaPath;\r
import org.opendaylight.controller.yang.model.api.Status;\r
import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;\r
-import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;\r
\r
/**\r
* Basic implementation of SchemaNodeBuilder.\r
*/\r
-public abstract class AbstractSchemaNodeBuilder implements SchemaNodeBuilder {\r
- protected final int line;\r
+public abstract class AbstractSchemaNodeBuilder extends AbstractBuilder implements SchemaNodeBuilder {\r
protected final QName qname;\r
- protected Builder parent;\r
protected SchemaPath schemaPath;\r
protected String description;\r
protected String reference;\r
protected Status status = Status.CURRENT;\r
protected List<UnknownSchemaNode> unknownNodes;\r
- protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();\r
\r
- protected AbstractSchemaNodeBuilder(final int line, final QName qname) {\r
- this.line = line;\r
+ protected AbstractSchemaNodeBuilder(final String moduleName, final int line, final QName qname) {\r
+ super(moduleName, line);\r
this.qname = qname;\r
}\r
\r
- @Override\r
- public int getLine() {\r
- return line;\r
- }\r
-\r
public QName getQName() {\r
return qname;\r
}\r
\r
- @Override\r
- public Builder getParent() {\r
- return parent;\r
- }\r
-\r
- @Override\r
- public void setParent(final Builder parent) {\r
- this.parent = parent;\r
- }\r
-\r
@Override\r
public SchemaPath getPath() {\r
return schemaPath;\r
}\r
}\r
\r
- @Override\r
- public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {\r
- return addedUnknownNodes;\r
- }\r
-\r
- @Override\r
- public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {\r
- addedUnknownNodes.add(unknownNode);\r
- }\r
-\r
public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {\r
this.unknownNodes = unknownNodes;\r
}\r
--- /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.yang.parser.builder.api;
+
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.TypeDefinition;
+
+/**
+ * Basic implementation for TypeAwareBuilder builders.
+ */
+public abstract class AbstractTypeAwareBuilder extends AbstractBuilder implements TypeAwareBuilder {
+ protected final QName qname;
+ protected TypeDefinition<?> type;
+ protected TypeDefinitionBuilder typedef;
+
+ public AbstractTypeAwareBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line);
+ this.qname = qname;
+ }
+
+ @Override
+ public QName getQName() {
+ return qname;
+ }
+
+ @Override
+ public TypeDefinition<?> getType() {
+ return type;
+ }
+
+ @Override
+ public TypeDefinitionBuilder getTypedef() {
+ return typedef;
+ }
+
+ @Override
+ public void setType(TypeDefinition<?> type) {
+ this.type = type;
+ this.typedef = null;
+ }
+
+ @Override
+ public void setTypedef(TypeDefinitionBuilder typedef) {
+ this.typedef = typedef;
+ this.type = null;
+ }
+
+}
*/
public interface Builder {
+ /**
+ * Get name of module in which this node is declared.
+ *
+ * @return module name
+ */
+ String getModuleName();
+
+ /**
+ * Set name of module in which this node is declared.
+ *
+ * @param moduleName
+ */
+ void setModuleName(String moduleName);
+
/**
* Get current line in yang file.
*
private boolean augmenting;
private boolean addedByUses;
- public AnyXmlBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
- super(line, qname);
+ public AnyXmlBuilder(final String moduleName, final int line, final QName qname, final SchemaPath schemaPath) {
+ super(moduleName, line, qname);
this.schemaPath = schemaPath;
instance = new AnyXmlSchemaNodeImpl(qname);
- constraints = new ConstraintsBuilder(line);
+ constraints = new ConstraintsBuilder(moduleName, line);
}
public AnyXmlBuilder(final AnyXmlBuilder builder) {
- super(builder.getLine(), builder.getQName());
+ super(builder.getModuleName(), builder.getLine(), builder.getQName());
parent = builder.getParent();
instance = new AnyXmlSchemaNodeImpl(qname);
constraints = builder.getConstraints();
private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();
private boolean resolved;
- AugmentationSchemaBuilderImpl(final int line, final String augmentTargetStr) {
- super(line, null);
+ AugmentationSchemaBuilderImpl(final String moduleName, final int line, final String augmentTargetStr) {
+ super(moduleName, line, null);
this.augmentTargetStr = augmentTargetStr;
final SchemaPath targetPath = ParserListenerUtils.parseAugmentPath(augmentTargetStr);
dirtyAugmentTarget = targetPath;
@Override
public void addGrouping(GroupingBuilder grouping) {
- throw new YangParseException(line, "augment can not contains grouping statement");
+ throw new YangParseException(moduleName, line, "augment can not contains grouping statement");
}
@Override
@Override
public void addTypedef(TypeDefinitionBuilder type) {
- throw new YangParseException(line, "Augmentation can not contains typedef statement.");
+ throw new YangParseException(moduleName, line, "Augmentation can not contains typedef statement.");
}
@Override
import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
import org.opendaylight.controller.yang.parser.util.Comparators;
import org.opendaylight.controller.yang.parser.util.ParserUtils;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements DataSchemaNodeBuilder,
AugmentationTargetBuilder, GroupingMember {
private final Set<ChoiceCaseBuilder> addedCases = new HashSet<ChoiceCaseBuilder>();
private String defaultCase;
- public ChoiceBuilder(final int line, final QName qname) {
- super(line, qname);
+ public ChoiceBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new ChoiceNodeImpl(qname);
- constraints = new ConstraintsBuilder(line);
+ constraints = new ConstraintsBuilder(moduleName, line);
}
public ChoiceBuilder(ChoiceBuilder b) {
- super(b.getLine(), b.getQName());
+ super(b.getModuleName(), b.getLine(), b.getQName());
parent = b.getParent();
instance = new ChoiceNodeImpl(qname);
constraints = b.getConstraints();
return addedCases;
}
- public void addChildNode(DataSchemaNodeBuilder childNode) {
- if (!(childNode instanceof ChoiceCaseBuilder)) {
- ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(childNode.getLine(), childNode.getQName());
- if (childNode.isAugmenting()) {
+ /**
+ * Add case node to this choice.
+ *
+ * If node is not declared with 'case' keyword, create new case builder and
+ * make this node child of newly created case.
+ *
+ * @param caseNode
+ * case node
+ */
+ public void addCase(DataSchemaNodeBuilder caseNode) {
+ QName caseQName = caseNode.getQName();
+ String caseName = caseQName.getLocalName();
+ for (ChoiceCaseBuilder addedCase : addedCases) {
+ if (addedCase.getQName().getLocalName().equals(caseName)) {
+ throw new YangParseException(caseNode.getModuleName(), caseNode.getLine(), "Can not add '" + caseNode
+ + "' to node '" + qname.getLocalName() + "' in module '" + moduleName
+ + "': case with same name already declared at line " + addedCase.getLine());
+ }
+ }
+
+ if (caseNode instanceof ChoiceCaseBuilder) {
+ addedCases.add((ChoiceCaseBuilder) caseNode);
+ } else {
+ ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(caseNode.getModuleName(), caseNode.getLine(),
+ caseQName);
+ if (caseNode.isAugmenting()) {
+ // if node is added by augmentation, set case builder augmenting
+ // as true and node augmenting as false
caseBuilder.setAugmenting(true);
- childNode.setAugmenting(false);
+ caseNode.setAugmenting(false);
}
- caseBuilder.setPath(childNode.getPath());
- SchemaPath newPath = ParserUtils.createSchemaPath(childNode.getPath(), childNode.getQName().getLocalName());
- childNode.setPath(newPath);
- caseBuilder.addChildNode(childNode);
+ caseBuilder.setPath(caseNode.getPath());
+ SchemaPath newPath = ParserUtils.createSchemaPath(caseNode.getPath(), caseQName.getLocalName(),
+ caseQName.getNamespace(), caseQName.getRevision(), caseQName.getPrefix());
+ caseNode.setPath(newPath);
+ caseBuilder.addChildNode(caseNode);
addedCases.add(caseBuilder);
- } else {
- addedCases.add((ChoiceCaseBuilder) childNode);
}
}
// AugmentationTarget args
private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
- ChoiceCaseBuilder(final int line, final QName qname) {
- super(line, qname);
+ ChoiceCaseBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new ChoiceCaseNodeImpl(qname);
- constraints = new ConstraintsBuilder(line);
+ constraints = new ConstraintsBuilder(moduleName, line);
}
@Override
@Override
public void addTypedef(TypeDefinitionBuilder typedefBuilder) {
- throw new YangParseException(line, "Can not add type definition to choice case.");
+ throw new YangParseException(moduleName, line, "Can not add type definition to choice case.");
}
@Override
@Override
public void setConfiguration(final Boolean configuration) {
- throw new YangParseException(line, "Can not add config statement to choice case.");
+ throw new YangParseException(moduleName, line, "Can not add config statement to choice case.");
}
@Override
import org.opendaylight.controller.yang.model.api.MustDefinition;
import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
import org.opendaylight.controller.yang.model.util.RevisionAwareXPathImpl;
-import org.opendaylight.controller.yang.parser.builder.api.Builder;
+import org.opendaylight.controller.yang.parser.builder.api.AbstractBuilder;
import org.opendaylight.controller.yang.parser.util.YangParseException;
-public final class ConstraintsBuilder implements Builder {
+public final class ConstraintsBuilder extends AbstractBuilder {
private final ConstraintDefinitionImpl instance;
- private final int line;
- private Builder parent;
private final Set<MustDefinition> mustDefinitions;
private String whenCondition;
private boolean mandatory;
private Integer min;
private Integer max;
- ConstraintsBuilder(final int line) {
- this.line = line;
+ ConstraintsBuilder(final String moduleName, final int line) {
+ super(moduleName, line);
instance = new ConstraintDefinitionImpl();
mustDefinitions = new HashSet<MustDefinition>();
}
return instance;
}
- @Override
- public int getLine() {
- return line;
- }
-
- @Override
- public Builder getParent() {
- return parent;
- }
-
- @Override
- public void setParent(final Builder parent) {
- this.parent = parent;
- }
-
@Override
public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
- throw new YangParseException(line, "Can not add unknown node to constraints.");
+ throw new YangParseException(moduleName, line, "Can not add unknown node to constraints.");
}
@Override
this.mandatory = mandatory;
}
-
private final class ConstraintDefinitionImpl implements ConstraintDefinition {
private RevisionAwareXPath whenCondition;
private Set<MustDefinition> mustConstraints;
import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
import org.opendaylight.controller.yang.parser.util.Comparators;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements
AugmentationTargetBuilder, DataSchemaNodeBuilder, GroupingMember {
// ContainerSchemaNode args
private boolean presence;
- public ContainerSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
- super(line, qname);
+ public ContainerSchemaNodeBuilder(final String moduleName, final int line, final QName qname,
+ final SchemaPath schemaPath) {
+ super(moduleName, line, qname);
this.schemaPath = schemaPath;
instance = new ContainerSchemaNodeImpl(qname);
- constraints = new ConstraintsBuilder(line);
+ constraints = new ConstraintsBuilder(moduleName, line);
}
public ContainerSchemaNodeBuilder(final ContainerSchemaNodeBuilder b) {
- super(b.getLine(), b.getQName());
+ super(b.getModuleName(), b.getLine(), b.getQName());
instance = new ContainerSchemaNodeImpl(b.getQName());
constraints = b.getConstraints();
schemaPath = b.getPath();
// CHILD NODES
final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
- if (childNodes == null) {
+ if (childNodes == null || childNodes.isEmpty()) {
for (DataSchemaNodeBuilder node : addedChildNodes) {
childs.put(node.getQName(), node.build());
}
@Override
public void addTypedef(final TypeDefinitionBuilder type) {
+ String typeName = type.getQName().getLocalName();
+ for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
+ throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
+ + "': typedef with same name already declared at line " + addedTypedef.getLine());
+ }
addedTypedefs.add(type);
}
import org.opendaylight.controller.yang.model.api.Deviation.Deviate;
import org.opendaylight.controller.yang.model.api.SchemaPath;
import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.controller.yang.parser.builder.api.Builder;
+import org.opendaylight.controller.yang.parser.builder.api.AbstractBuilder;
import org.opendaylight.controller.yang.parser.util.Comparators;
import org.opendaylight.controller.yang.parser.util.ParserListenerUtils;
import org.opendaylight.controller.yang.parser.util.YangParseException;
-public final class DeviationBuilder implements Builder {
- private final int line;
+public final class DeviationBuilder extends AbstractBuilder {
private final String targetPathStr;
- private Builder parent;
private boolean isBuilt;
private final DeviationImpl instance;
private String reference;
private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
- DeviationBuilder(final int line, final String targetPathStr) {
- if(!targetPathStr.startsWith("/")) {
- throw new YangParseException(line, "Deviation argument string must be an absolute schema node identifier.");
+ DeviationBuilder(final String moduleName, final int line, final String targetPathStr) {
+ super(moduleName, line);
+ if (!targetPathStr.startsWith("/")) {
+ throw new YangParseException(moduleName, line,
+ "Deviation argument string must be an absolute schema node identifier.");
}
- this.line = line;
this.targetPathStr = targetPathStr;
this.targetPath = ParserListenerUtils.parseAugmentPath(targetPathStr);
instance = new DeviationImpl();
@Override
public Deviation build() {
- if(targetPath == null) {
- throw new YangParseException(line, "Unresolved deviation target");
+ if (targetPath == null) {
+ throw new YangParseException(moduleName, line, "Unresolved deviation target");
}
- if(!isBuilt) {
+ if (!isBuilt) {
instance.setTargetPath(targetPath);
instance.setReference(reference);
return instance;
}
- @Override
- public int getLine() {
- return line;
- }
-
- @Override
- public Builder getParent() {
- return parent;
- }
-
- @Override
- public void setParent(final Builder parent) {
- this.parent = parent;
- }
-
- @Override
- public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
- return addedUnknownNodes;
- }
-
- @Override
- public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
- addedUnknownNodes.add(unknownNode);
- }
-
public SchemaPath getTargetPath() {
return targetPath;
}
} else if ("delete".equals(deviate)) {
instance.setDeviate(Deviate.DELETE);
} else {
- throw new YangParseException(line,
- "Unsupported type of 'deviate' statement: " + deviate);
+ throw new YangParseException(moduleName, line, "Unsupported type of 'deviate' statement: " + deviate);
}
}
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result
- + ((targetPath == null) ? 0 : targetPath.hashCode());
- result = prime * result
- + ((deviate == null) ? 0 : deviate.hashCode());
- result = prime * result
- + ((reference == null) ? 0 : reference.hashCode());
+ result = prime * result + ((targetPath == null) ? 0 : targetPath.hashCode());
+ result = prime * result + ((deviate == null) ? 0 : deviate.hashCode());
+ result = prime * result + ((reference == null) ? 0 : reference.hashCode());
return result;
}
@Override
public String toString() {
- StringBuilder sb = new StringBuilder(
- DeviationImpl.class.getSimpleName());
+ StringBuilder sb = new StringBuilder(DeviationImpl.class.getSimpleName());
sb.append("[");
sb.append("targetPath=" + targetPath);
sb.append(", deviate=" + deviate);
private boolean isBuilt;
private final ExtensionDefinitionImpl instance;
- ExtensionBuilder(final int line, final QName qname) {
- super(line, qname);
+ ExtensionBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new ExtensionDefinitionImpl(qname);
}
private boolean isBuilt;
private final FeatureDefinitionImpl instance;
- FeatureBuilder(final int line, final QName qname) {
- super(line, qname);
+ FeatureBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new FeatureDefinitionImpl(qname);
}
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.TreeSet;
import org.opendaylight.controller.yang.common.QName;
import org.opendaylight.controller.yang.model.api.TypeDefinition;
import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
import org.opendaylight.controller.yang.model.api.UsesNode;
-import org.opendaylight.controller.yang.parser.builder.api.Builder;
+import org.opendaylight.controller.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
import org.opendaylight.controller.yang.parser.util.Comparators;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
-public final class GroupingBuilderImpl implements GroupingBuilder {
- private Builder parent;
+public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder implements GroupingBuilder {
private boolean isBuilt;
private final GroupingDefinitionImpl instance;
- private final int line;
- private final QName qname;
private SchemaPath schemaPath;
private String description;
private String reference;
private Status status = Status.CURRENT;
private boolean addedByUses;
- private Set<DataSchemaNode> childNodes;
- private final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<DataSchemaNodeBuilder>();
-
- private Set<GroupingDefinition> groupings;
- private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
-
private Set<TypeDefinition<?>> typedefs;
private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
private Set<UsesNode> usesNodes;
private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
- private List<UnknownSchemaNode> unknownNodes;
- private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
-
- public GroupingBuilderImpl(final QName qname, final int line) {
- this.qname = qname;
+ public GroupingBuilderImpl(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new GroupingDefinitionImpl(qname);
- this.line = line;
}
public GroupingBuilderImpl(GroupingBuilder builder) {
- qname = builder.getQName();
+ super(builder.getModuleName(), builder.getLine(), builder.getQName());
parent = builder.getParent();
instance = new GroupingDefinitionImpl(qname);
- line = builder.getLine();
schemaPath = builder.getPath();
description = builder.getDescription();
reference = builder.getReference();
instance.setAddedByUses(addedByUses);
// CHILD NODES
- final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
- if (childNodes == null) {
+ final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
+ if (childNodes == null || childNodes.isEmpty()) {
for (DataSchemaNodeBuilder node : addedChildNodes) {
childs.put(node.getQName(), node.build());
}
return instance;
}
- @Override
- public int getLine() {
- return line;
- }
-
- @Override
- public Builder getParent() {
- return parent;
- }
-
- @Override
- public void setParent(final Builder parent) {
- this.parent = parent;
- }
-
- @Override
- public QName getQName() {
- return qname;
- }
@Override
public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
@Override
public void addTypedef(final TypeDefinitionBuilder type) {
+ String typeName = type.getQName().getLocalName();
+ for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
+ throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
+ + "': typedef with same name already declared at line " + addedTypedef.getLine());
+ }
addedTypedefs.add(type);
}
this.addedByUses = addedByUses;
}
- @Override
- public Set<DataSchemaNode> getChildNodes() {
- return childNodes;
- }
-
- @Override
- public void addChildNode(final DataSchemaNodeBuilder childNode) {
- addedChildNodes.add(childNode);
- }
-
- @Override
- public Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
- return addedChildNodes;
- }
-
- @Override
- public DataSchemaNodeBuilder getDataChildByName(final String name) {
- for(DataSchemaNodeBuilder child : addedChildNodes) {
- if(child.getQName().getLocalName().equals(name)) {
- return child;
- }
- }
- return null;
- }
-
- public void setChildNodes(final Set<DataSchemaNode> childNodes) {
- this.childNodes = childNodes;
- }
-
- @Override
- public Set<GroupingDefinition> getGroupings() {
- return Collections.emptySet();
- }
-
- @Override
- public Set<GroupingBuilder> getGroupingBuilders() {
- return addedGroupings;
- }
-
- @Override
- public void addGrouping(final GroupingBuilder grouping) {
- addedGroupings.add(grouping);
- }
-
- public void setGroupings(final Set<GroupingDefinition> groupings) {
- this.groupings = groupings;
- }
-
@Override
public Set<UsesNodeBuilder> getUses() {
return addedUsesNodes;
this.usesNodes = usesNodes;
}
- @Override
- public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
- return addedUnknownNodes;
- }
-
- @Override
- public void addUnknownNodeBuilder(final UnknownSchemaNodeBuilder unknownNode) {
- addedUnknownNodes.add(unknownNode);
- }
-
- public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
- this.unknownNodes = unknownNodes;
- }
-
@Override
public String toString() {
return "grouping " + qname.getLocalName();
private IdentitySchemaNode baseIdentity;
private String baseIdentityName;
- IdentitySchemaNodeBuilder(final int line, final QName qname) {
- super(line, qname);
+ IdentitySchemaNodeBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new IdentitySchemaNodeImpl(qname);
}
private final SchemaPath schemaPath;
private QName baseQName;
- IdentityrefTypeBuilder(final String baseString, final SchemaPath schemaPath, final int line) {
- super(line, null);
+ IdentityrefTypeBuilder(final String moduleName, final int line, final String baseString, final SchemaPath schemaPath) {
+ super(moduleName, line, null);
this.baseString = baseString;
this.schemaPath = schemaPath;
}
@Override
public void setType(final TypeDefinition<?> type) {
- throw new YangParseException(line, "Can not set type to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set type to " + NAME);
}
@Override
public void setTypedef(final TypeDefinitionBuilder tdb) {
- throw new YangParseException(line, "Can not set type to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set type to " + NAME);
}
@Override
public void setPath(final SchemaPath schemaPath) {
- throw new YangParseException(line, "Can not set path to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set path to " + NAME);
}
@Override
public void setDescription(final String description) {
- throw new YangParseException(line, "Can not set description to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set description to " + NAME);
}
@Override
public void setReference(final String reference) {
- throw new YangParseException(line, "Can not set reference to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set reference to " + NAME);
}
@Override
public void setStatus(final Status status) {
- throw new YangParseException(line, "Can not set status to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set status to " + NAME);
}
@Override
@Override
public void setAddedByUses(final boolean addedByUses) {
- throw new YangParseException(line, "Identityref type can not be added by uses.");
+ throw new YangParseException(moduleName, line, "Identityref type can not be added by uses.");
}
@Override
@Override
public void addUnknownNodeBuilder(final UnknownSchemaNodeBuilder unknownNode) {
- throw new YangParseException(line, "Can not add unknown node to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not add unknown node to " + NAME);
}
@Override
@Override
public void setRanges(List<RangeConstraint> ranges) {
- throw new YangParseException(line, "Can not set ranges to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set ranges to " + NAME);
}
@Override
@Override
public void setLengths(List<LengthConstraint> lengths) {
- throw new YangParseException(line, "Can not set lengths to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set lengths to " + NAME);
}
@Override
@Override
public void setPatterns(List<PatternConstraint> patterns) {
- throw new YangParseException(line, "Can not set patterns to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set patterns to " + NAME);
}
@Override
@Override
public void setFractionDigits(Integer fractionDigits) {
- throw new YangParseException(line, "Can not set fraction digits to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set fraction digits to " + NAME);
}
@Override
@Override
public void setDefaultValue(Object defaultValue) {
- throw new YangParseException(line, "Can not set default value to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set default value to " + NAME);
}
@Override
@Override
public void setUnits(String units) {
- throw new YangParseException(line, "Can not set units to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set units to " + NAME);
}
@Override
// LeafListSchemaNode args
private boolean userOrdered;
- public LeafListSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
- super(line, qname);
+ public LeafListSchemaNodeBuilder(final String moduleName, final int line, final QName qname,
+ final SchemaPath schemaPath) {
+ super(moduleName, line, qname);
this.schemaPath = schemaPath;
instance = new LeafListSchemaNodeImpl(qname);
- constraints = new ConstraintsBuilder(line);
+ constraints = new ConstraintsBuilder(moduleName, line);
}
public LeafListSchemaNodeBuilder(final LeafListSchemaNodeBuilder b) {
- super(b.getLine(), b.getQName());
+ super(b.getModuleName(), b.getLine(), b.getQName());
instance = new LeafListSchemaNodeImpl(qname);
type = b.getType();
private String defaultStr;
private String unitsStr;
- public LeafSchemaNodeBuilder(final QName qname, final SchemaPath schemaPath, final int line) {
- super(line, qname);
+ public LeafSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath schemaPath) {
+ super(moduleName, line, qname);
this.schemaPath = schemaPath;
instance = new LeafSchemaNodeImpl(qname);
- constraints = new ConstraintsBuilder(line);
+ constraints = new ConstraintsBuilder(moduleName, line);
}
public LeafSchemaNodeBuilder(final LeafSchemaNodeBuilder b) {
- super(b.getLine(), b.getQName());
+ super(b.getModuleName(), b.getLine(), b.getQName());
instance = new LeafSchemaNodeImpl(qname);
constraints = b.getConstraints();
schemaPath = b.getPath();
import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
import org.opendaylight.controller.yang.parser.util.Comparators;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements DataSchemaNodeBuilder,
AugmentationTargetBuilder, GroupingMember {
private List<QName> keyDefinition = Collections.emptyList();
private boolean userOrdered;
- public ListSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
- super(line, qname);
+ public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath schemaPath) {
+ super(moduleName, line, qname);
this.schemaPath = schemaPath;
instance = new ListSchemaNodeImpl(qname);
- constraints = new ConstraintsBuilder(line);
+ constraints = new ConstraintsBuilder(moduleName, line);
}
public ListSchemaNodeBuilder(final ListSchemaNodeBuilder b) {
- super(b.getLine(), b.getQName());
+ super(b.getModuleName(), b.getLine(), b.getQName());
instance = new ListSchemaNodeImpl(b.getQName());
constraints = b.getConstraints();
schemaPath = b.getPath();
// CHILD NODES
final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
- if (childNodes == null) {
+ if (childNodes == null || childNodes.isEmpty()) {
for (DataSchemaNodeBuilder node : addedChildNodes) {
childs.put(node.getQName(), node.build());
}
@Override
public void addTypedef(final TypeDefinitionBuilder type) {
+ String typeName = type.getQName().getLocalName();
+ for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
+ throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
+ + "': typedef with same name already declared at line " + addedTypedef.getLine());
+ }
addedTypedefs.add(type);
}
private final List<UnknownSchemaNodeBuilder> allUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
public ModuleBuilder(final String name) {
- super(0, null);
+ super(name, 0, null);
this.name = name;
instance = new ModuleImpl(name);
+ actualPath.push(this);
}
/**
}
public ExtensionBuilder addExtension(final QName qname, final int line) {
- final ExtensionBuilder builder = new ExtensionBuilder(line, qname);
+ final String extName = qname.getLocalName();
+ for (ExtensionBuilder addedExtension : addedExtensions) {
+ if (addedExtension.getQName().getLocalName().equals(extName)) {
+ throw new YangParseException(moduleName, line, "Can not add extension '" + extName
+ + "': extension with same name already declared at line " + addedExtension.getLine());
+ }
+ }
+ final ExtensionBuilder builder = new ExtensionBuilder(name, line, qname);
addedExtensions.add(builder);
return builder;
}
- public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName containerName,
- final SchemaPath schemaPath) {
- final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(line, containerName, schemaPath);
+ public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName qname, final SchemaPath schemaPath) {
+ final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
Builder parent = getActualNode();
builder.setParent(parent);
- addChildToParent(parent, builder, containerName.getLocalName());
+ addChildToParent(parent, builder, qname.getLocalName());
return builder;
}
- public ListSchemaNodeBuilder addListNode(final int line, final QName listName, final SchemaPath schemaPath) {
- final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(line, listName, schemaPath);
+ public ListSchemaNodeBuilder addListNode(final int line, final QName qname, final SchemaPath schemaPath) {
+ final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(name, line, qname, schemaPath);
Builder parent = getActualNode();
builder.setParent(parent);
- addChildToParent(parent, builder, listName.getLocalName());
+ addChildToParent(parent, builder, qname.getLocalName());
return builder;
}
- public LeafSchemaNodeBuilder addLeafNode(final int line, final QName leafName, final SchemaPath schemaPath) {
- final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(leafName, schemaPath, line);
+ public LeafSchemaNodeBuilder addLeafNode(final int line, final QName qname, final SchemaPath schemaPath) {
+ final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(name, line, qname, schemaPath);
Builder parent = getActualNode();
builder.setParent(parent);
- addChildToParent(parent, builder, leafName.getLocalName());
+ addChildToParent(parent, builder, qname.getLocalName());
return builder;
}
- public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName leafListName,
- final SchemaPath schemaPath) {
- final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(line, leafListName, schemaPath);
+ public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName qname, final SchemaPath schemaPath) {
+ final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(name, line, qname, schemaPath);
Builder parent = getActualNode();
builder.setParent(parent);
- addChildToParent(parent, builder, leafListName.getLocalName());
+ addChildToParent(parent, builder, qname.getLocalName());
return builder;
}
public GroupingBuilder addGrouping(final int line, final QName qname) {
- final GroupingBuilder builder = new GroupingBuilderImpl(qname, line);
+ final GroupingBuilder builder = new GroupingBuilderImpl(name, line, qname);
Builder parent = getActualNode();
builder.setParent(parent);
- if (parent == null) {
- for (GroupingBuilder child : addedGroupings) {
- if (child.getQName().getLocalName().equals(qname.getLocalName())) {
- throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+ String groupingName = qname.getLocalName();
+ if (parent.equals(this)) {
+ for (GroupingBuilder addedGrouping : addedGroupings) {
+ if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
+ throw new YangParseException(name, line, "grouping with same name '" + groupingName
+ + "' already declared at line " + addedGrouping.getLine());
}
}
addedGroupings.add(builder);
} else {
if (parent instanceof DataNodeContainerBuilder) {
DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
- for (DataSchemaNodeBuilder child : parentNode.getChildNodeBuilders()) {
- if (child.getQName().getLocalName().equals(qname.getLocalName())) {
- throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+ for (GroupingBuilder addedGrouping : parentNode.getGroupingBuilders()) {
+ if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
+ throw new YangParseException(name, line, "grouping with same name '" + groupingName
+ + "' already declared at line " + addedGrouping.getLine());
}
}
parentNode.addGrouping(builder);
} else if (parent instanceof RpcDefinitionBuilder) {
RpcDefinitionBuilder parentNode = (RpcDefinitionBuilder) parent;
for (GroupingBuilder child : parentNode.getGroupings()) {
- if (child.getQName().getLocalName().equals(qname.getLocalName())) {
- throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+ if (child.getQName().getLocalName().equals(groupingName)) {
+ throw new YangParseException(name, line, "grouping with same name '" + groupingName
+ + "' already declared at line " + child.getLine());
}
}
parentNode.addGrouping(builder);
} else {
- throw new YangParseException(name, line, "Unresolved parent of grouping " + qname.getLocalName());
+ throw new YangParseException(name, line, "Unresolved parent of grouping " + groupingName);
}
}
}
public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr) {
- final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(line, augmentTargetStr);
+ final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr);
Builder parent = getActualNode();
builder.setParent(parent);
- if (parent == null) {
+ if (parent.equals(this)) {
+ // augment can be declared only under 'module' ...
addedAugments.add(builder);
} else {
- // augment can only be in 'module' or 'uses' statement
+ // ... or 'uses' statement
if (parent instanceof UsesNodeBuilder) {
((UsesNodeBuilder) parent).addAugment(builder);
} else {
- throw new YangParseException(name, line, "Augment can be declared only under module or uses.");
+ throw new YangParseException(name, line, "Augment can be declared only under module or uses statement.");
}
}
allAugments.add(builder);
}
public UsesNodeBuilder addUsesNode(final int line, final String groupingPathStr) {
- final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(line, groupingPathStr);
+ final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, groupingPathStr);
Builder parent = getActualNode();
usesBuilder.setParent(parent);
- if (parent == null) {
+ if (parent.equals(this)) {
addedUsesNodes.add(usesBuilder);
} else {
if (!(parent instanceof DataNodeContainerBuilder)) {
return usesBuilder;
}
- public void addRefine(final RefineHolder refine, final List<String> parentPath) {
- final List<String> path = new ArrayList<String>(parentPath);
-
- if (actualPath.isEmpty()) {
+ public void addRefine(final RefineHolder refine) {
+ final Builder parent = getActualNode();
+ if (!(parent instanceof UsesNodeBuilder)) {
throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
- } else {
- final Builder parent = getActualNode();
- if (parent instanceof UsesNodeBuilder) {
- ((UsesNodeBuilder) parent).addRefine(refine);
- } else {
- throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
- }
- refine.setParent(parent);
}
-
- path.add(refine.getName());
+ ((UsesNodeBuilder) parent).addRefine(refine);
+ refine.setParent(parent);
}
public RpcDefinitionBuilder addRpc(final int line, final QName qname) {
Builder parent = getActualNode();
- if (parent != null) {
+ if (!(parent.equals(this))) {
throw new YangParseException(name, line, "rpc can be defined only in module or submodule");
}
- final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(line, qname);
+ final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(name, line, qname);
+
+ String rpcName = qname.getLocalName();
for (RpcDefinitionBuilder rpc : addedRpcs) {
- if (rpc.getQName().getLocalName().equals(qname.getLocalName())) {
- throw new YangParseException(name, line, "Duplicate node found at line " + rpc.getLine());
+ if (rpc.getQName().getLocalName().equals(rpcName)) {
+ throw new YangParseException(name, line, "rpc with same name '" + rpcName
+ + "' already declared at line " + rpc.getLine());
+ }
+ }
+ for (DataSchemaNodeBuilder addedChild : addedChildNodes) {
+ if (addedChild.getQName().getLocalName().equals(rpcName)) {
+ throw new YangParseException(name, line, "Can not add rpc: node with same name '" + rpcName
+ + "' already declared at line " + addedChild.getLine());
+ }
+ }
+ for (NotificationBuilder addedNotification : addedNotifications) {
+ if (addedNotification.getQName().getLocalName().equals(rpcName)) {
+ throw new YangParseException(name, line, "Can not add rpc: notification with same name '" + rpcName
+ + "' already declared at line " + addedNotification.getLine());
}
}
addedRpcs.add(rpcBuilder);
return rpcBuilder;
}
- public ContainerSchemaNodeBuilder addRpcInput(final SchemaPath schemaPath, final QName inputQName, final int line) {
+ public ContainerSchemaNodeBuilder addRpcInput(final int line, final QName qname, final SchemaPath schemaPath) {
final Builder parent = getActualNode();
if (!(parent instanceof RpcDefinitionBuilder)) {
throw new YangParseException(name, line, "input can be defined only in rpc statement");
}
final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
- final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(line, inputQName, schemaPath);
+ final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
inputBuilder.setParent(rpc);
rpc.setInput(inputBuilder);
return inputBuilder;
}
- public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName outputQName, final int line) {
- final Builder parent = actualPath.getFirst();
+ public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) {
+ final Builder parent = getActualNode();
if (!(parent instanceof RpcDefinitionBuilder)) {
throw new YangParseException(name, line, "output can be defined only in rpc statement");
}
final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
- final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(line, outputQName, schemaPath);
+ final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
outputBuilder.setParent(rpc);
rpc.setOutput(outputBuilder);
return outputBuilder;
}
- public NotificationBuilder addNotification(final QName notificationName, final List<String> parentPath,
- final int line) {
- if (!(actualPath.isEmpty())) {
+ public NotificationBuilder addNotification(final int line, final QName qname) {
+ final Builder parent = getActualNode();
+ if (!(parent.equals(this))) {
throw new YangParseException(name, line, "notification can be defined only in module or submodule");
}
+
+ String notificationName = qname.getLocalName();
for (NotificationBuilder nb : addedNotifications) {
- if (nb.getQName().equals(notificationName)) {
- throw new YangParseException(name, line, "Duplicate node found at line " + nb.getLine());
+ if (nb.getQName().equals(qname)) {
+ throw new YangParseException(name, line, "notification with same name '" + notificationName
+ + "' already declared at line " + nb.getLine());
+ }
+ }
+ for (RpcDefinitionBuilder rpc : addedRpcs) {
+ if (rpc.getQName().getLocalName().equals(notificationName)) {
+ throw new YangParseException(name, line, "Can not add notification: rpc with same name '"
+ + notificationName + "' already declared at line " + rpc.getLine());
+ }
+ }
+ for (DataSchemaNodeBuilder addedChild : addedChildNodes) {
+ if (addedChild.getQName().getLocalName().equals(notificationName)) {
+ throw new YangParseException(name, line, "Can not add notification: node with same name '"
+ + notificationName + "' already declared at line " + addedChild.getLine());
}
}
- final NotificationBuilder builder = new NotificationBuilder(line, notificationName);
+ final NotificationBuilder builder = new NotificationBuilder(name, line, qname);
addedNotifications.add(builder);
return builder;
}
- public FeatureBuilder addFeature(final int line, final QName featureName) {
+ public FeatureBuilder addFeature(final int line, final QName qname) {
Builder parent = getActualNode();
- if (parent != null) {
+ if (!(parent.equals(this))) {
throw new YangParseException(name, line, "feature can be defined only in module or submodule");
}
- final FeatureBuilder builder = new FeatureBuilder(line, featureName);
- for (FeatureBuilder fb : addedFeatures) {
- if (fb.getQName().getLocalName().equals(featureName.getLocalName())) {
- throw new YangParseException(name, line, "Duplicate node found at line " + fb.getLine());
+ final FeatureBuilder builder = new FeatureBuilder(name, line, qname);
+
+ String featureName = qname.getLocalName();
+ for (FeatureBuilder addedFeature : addedFeatures) {
+ if (addedFeature.getQName().getLocalName().equals(featureName)) {
+ throw new YangParseException(name, line, "feature with same name '" + featureName
+ + "' already declared at line " + addedFeature.getLine());
}
}
addedFeatures.add(builder);
return builder;
}
- public ChoiceBuilder addChoice(final int line, final QName choiceName) {
- final ChoiceBuilder builder = new ChoiceBuilder(line, choiceName);
+ public ChoiceBuilder addChoice(final int line, final QName qname) {
+ final ChoiceBuilder builder = new ChoiceBuilder(name, line, qname);
Builder parent = getActualNode();
builder.setParent(parent);
- addChildToParent(parent, builder, choiceName.getLocalName());
+ addChildToParent(parent, builder, qname.getLocalName());
return builder;
}
- public ChoiceCaseBuilder addCase(final int line, final QName caseName) {
+ public ChoiceCaseBuilder addCase(final int line, final QName qname) {
Builder parent = getActualNode();
- if (parent == null) {
+ if (parent == null || parent.equals(this)) {
throw new YangParseException(name, line, "'case' parent not found");
}
- final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(line, caseName);
+ final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(name, line, qname);
builder.setParent(parent);
if (parent instanceof ChoiceBuilder) {
- ((ChoiceBuilder) parent).addChildNode(builder);
+ ((ChoiceBuilder) parent).addCase(builder);
} else if (parent instanceof AugmentationSchemaBuilder) {
((AugmentationSchemaBuilder) parent).addChildNode(builder);
} else {
- throw new YangParseException(name, line, "Unresolved parent of 'case' " + caseName.getLocalName());
+ throw new YangParseException(name, line, "Unresolved parent of 'case' " + qname.getLocalName());
}
return builder;
}
- public AnyXmlBuilder addAnyXml(final int line, final QName anyXmlName, final SchemaPath schemaPath) {
- final AnyXmlBuilder builder = new AnyXmlBuilder(line, anyXmlName, schemaPath);
+ public AnyXmlBuilder addAnyXml(final int line, final QName qname, final SchemaPath schemaPath) {
+ final AnyXmlBuilder builder = new AnyXmlBuilder(name, line, qname, schemaPath);
Builder parent = getActualNode();
builder.setParent(parent);
- addChildToParent(parent, builder, anyXmlName.getLocalName());
+ addChildToParent(parent, builder, qname.getLocalName());
return builder;
}
@Override
public void addTypedef(TypeDefinitionBuilder typedefBuilder) {
+ String nodeName = typedefBuilder.getQName().getLocalName();
for (TypeDefinitionBuilder tdb : addedTypedefs) {
- if (tdb.getQName().getLocalName().equals(typedefBuilder.getQName().getLocalName())) {
- throw new YangParseException(name, typedefBuilder.getLine(), "Duplicate node found at line "
- + tdb.getLine());
+ if (tdb.getQName().getLocalName().equals(nodeName)) {
+ throw new YangParseException(name, typedefBuilder.getLine(), "typedef with same name '" + nodeName
+ + "' already declared at line " + tdb.getLine());
}
}
addedTypedefs.add(typedefBuilder);
}
- public TypeDefinitionBuilderImpl addTypedef(final int line, final QName typeDefName) {
- final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typeDefName, line);
+ public TypeDefinitionBuilderImpl addTypedef(final int line, final QName qname) {
+ final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(name, line, qname);
Builder parent = getActualNode();
builder.setParent(parent);
- if (parent == null) {
+ String typedefName = qname.getLocalName();
+ if (parent.equals(this)) {
for (TypeDefinitionBuilder tdb : addedTypedefs) {
- if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) {
- throw new YangParseException(name, builder.getLine(), "Duplicate node found at line "
- + tdb.getLine());
+ if (tdb.getQName().getLocalName().equals(typedefName)) {
+ throw new YangParseException(name, line, "typedef with same name '" + typedefName
+ + "' already declared at line " + tdb.getLine());
}
}
addedTypedefs.add(builder);
} else {
if (parent instanceof DataNodeContainerBuilder) {
DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
- for (DataSchemaNodeBuilder child : parentNode.getChildNodeBuilders()) {
- if (child.getQName().getLocalName().equals(typeDefName.getLocalName())) {
- throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+ for (TypeDefinitionBuilder child : parentNode.getTypeDefinitionBuilders()) {
+ if (child.getQName().getLocalName().equals(typedefName)) {
+ throw new YangParseException(name, line, "typedef with same name '" + typedefName
+ + "' already declared at line " + child.getLine());
}
}
parentNode.addTypedef(builder);
RpcDefinitionBuilder rpcParent = (RpcDefinitionBuilder) parent;
for (TypeDefinitionBuilder tdb : rpcParent.getTypeDefinitions()) {
if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) {
- throw new YangParseException(name, builder.getLine(), "Duplicate node found at line "
- + tdb.getLine());
+ throw new YangParseException(name, line, "typedef with same name '" + typedefName
+ + "' already declared at line " + tdb.getLine());
}
}
rpcParent.addTypedef(builder);
} else {
- throw new YangParseException(name, line, "Unresolved parent of typedef " + typeDefName.getLocalName());
+ throw new YangParseException(name, line, "Unresolved parent of typedef " + typedefName);
}
}
public UnionTypeBuilder addUnionType(final int line, final URI namespace, final Date revision) {
final Builder parent = getActualNode();
if (parent == null) {
- throw new YangParseException(line, "Error while parsing union type");
+ throw new YangParseException(name, line, "Unresolved parent of union type");
} else {
- final UnionTypeBuilder union = new UnionTypeBuilder(line);
+ final UnionTypeBuilder union = new UnionTypeBuilder(name, line);
if (parent instanceof TypeAwareBuilder) {
((TypeAwareBuilder) parent).setTypedef(union);
return union;
}
public void addIdentityrefType(final int line, final SchemaPath schemaPath, final String baseString) {
- final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(baseString, schemaPath, line);
+ final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(name, line, baseString, schemaPath);
final Builder parent = getActualNode();
if (parent == null) {
- throw new YangParseException(line, "Error while parsing identityref type.");
+ throw new YangParseException(name, line, "Unresolved parent of identityref type.");
} else {
if (parent instanceof TypeAwareBuilder) {
final TypeAwareBuilder typeParent = (TypeAwareBuilder) parent;
public DeviationBuilder addDeviation(final int line, final String targetPath) {
Builder parent = getActualNode();
- if (parent != null) {
+ if (!(parent.equals(this))) {
throw new YangParseException(name, line, "deviation can be defined only in module or submodule");
}
- final DeviationBuilder builder = new DeviationBuilder(line, targetPath);
+ final DeviationBuilder builder = new DeviationBuilder(name, line, targetPath);
addedDeviations.add(builder);
return builder;
}
public IdentitySchemaNodeBuilder addIdentity(final QName qname, final List<String> parentPath, final int line) {
Builder parent = getActualNode();
- if (parent != null) {
+ if (!(parent.equals(this))) {
throw new YangParseException(name, line, "identity can be defined only in module or submodule");
}
+ String identityName = qname.getLocalName();
for (IdentitySchemaNodeBuilder idBuilder : addedIdentities) {
if (idBuilder.getQName().equals(qname)) {
- throw new YangParseException(name, line, "Duplicate node found at line " + idBuilder.getLine());
+ throw new YangParseException(name, line, "identity with same name '" + identityName
+ + "' already declared at line " + idBuilder.getLine());
}
}
- final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(line, qname);
+ final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(name, line, qname);
addedIdentities.add(builder);
return builder;
}
public UnknownSchemaNodeBuilder addUnknownSchemaNode(final int line, final QName qname) {
final Builder parent = getActualNode();
- final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(line, qname);
+ final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(name, line, qname);
builder.setParent(parent);
allUnknownNodes.add(builder);
- if (parent == null) {
+ if (parent.equals(this)) {
addedUnknownNodes.add(builder);
} else {
if (parent instanceof SchemaNodeBuilder) {
}
}
- private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childLocalName) {
+ /**
+ * Add child to parent. Method checks for duplicates and add given child
+ * node to parent. If node with same name is found, throws exception. If
+ * parent is null, child node will be added directly to module.
+ *
+ * @param parent
+ * @param child
+ * @param childName
+ */
+ private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childName) {
final int line = child.getLine();
- if (parent == null) {
+ if (parent.equals(this)) {
// if parent == null => node is defined under module
// All leafs, leaf-lists, lists, containers, choices, rpcs,
// notifications, and anyxmls defined within a parent node or at the
// top level of the module or its submodules share the same
// identifier namespace.
for (DataSchemaNodeBuilder childNode : addedChildNodes) {
- if (childNode.getQName().getLocalName().equals(childLocalName)) {
- throw new YangParseException(name, line, "Duplicate node found at line " + childNode.getLine());
+ if (childNode.getQName().getLocalName().equals(childName)) {
+ throw new YangParseException(name, line, "Can not add '" + child
+ + "': node with same name already declared at line " + childNode.getLine());
}
}
for (RpcDefinitionBuilder rpc : addedRpcs) {
- if (rpc.getQName().getLocalName().equals(childLocalName)) {
- throw new YangParseException(name, line, "Duplicate node found at line " + rpc.getLine());
+ if (rpc.getQName().getLocalName().equals(childName)) {
+ throw new YangParseException(name, line, "Can not add '" + child
+ + "': rpc with same name already declared at line " + rpc.getLine());
}
}
for (NotificationBuilder notification : addedNotifications) {
- if (notification.getQName().getLocalName().equals(childLocalName)) {
- throw new YangParseException(name, line, "Duplicate node found at line " + notification.getLine());
+ if (notification.getQName().getLocalName().equals(childName)) {
+ throw new YangParseException(name, line, "Can not add '" + child
+ + "': notification with same name already declared at line " + notification.getLine());
}
}
addedChildNodes.add(child);
if (parent instanceof DataNodeContainerBuilder) {
DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
for (DataSchemaNodeBuilder childNode : parentNode.getChildNodeBuilders()) {
- if (childNode.getQName().getLocalName().equals(childLocalName)) {
- throw new YangParseException(name, line, "Duplicate node found at line " + childNode.getLine());
+ if (childNode.getQName().getLocalName().equals(childName)) {
+ throw new YangParseException(name, line, "Can not add '" + child + "': node with same name '"
+ + childName + "' already declared at line " + childNode.getLine());
}
}
parentNode.addChildNode(child);
} else if (parent instanceof ChoiceBuilder) {
ChoiceBuilder parentNode = (ChoiceBuilder) parent;
for (ChoiceCaseBuilder caseBuilder : parentNode.getCases()) {
- if (caseBuilder.getQName().getLocalName().equals(childLocalName)) {
- throw new YangParseException(name, line, "Duplicate node found at line "
- + caseBuilder.getLine());
+ if (caseBuilder.getQName().getLocalName().equals(childName)) {
+ throw new YangParseException(name, line, "Can not add '" + child + "': case with same name '"
+ + childName + "' already declared at line " + caseBuilder.getLine());
}
}
- parentNode.addChildNode(child);
+ parentNode.addCase(child);
} else {
- throw new YangParseException(name, line, "Unresolved parent of node '" + childLocalName + "'.");
+ throw new YangParseException(name, line, "Unresolved parent of node '" + childName + "'.");
}
}
}
private Set<AugmentationSchema> augmentations;
private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
- NotificationBuilder(final int line, final QName qname) {
- super(line, qname);
+ NotificationBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new NotificationDefinitionImpl(qname);
}
private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
- RpcDefinitionBuilder(final int line, final QName qname) {
- super(line, qname);
+ RpcDefinitionBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
this.instance = new RpcDefinitionImpl(qname);
}
private Object defaultValue;
private boolean addedByUses;
- public TypeDefinitionBuilderImpl(final QName qname, final int line) {
- super(line, qname);
+ public TypeDefinitionBuilderImpl(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
}
public TypeDefinitionBuilderImpl(TypeDefinitionBuilder tdb) {
- super(tdb.getLine(), tdb.getQName());
+ super(tdb.getModuleName(), tdb.getLine(), tdb.getQName());
schemaPath = tdb.getPath();
type = tdb.getType();
private SchemaPath path;
- public UnionTypeBuilder(final int line) {
- super(line, null);
+ public UnionTypeBuilder(final String moduleName, final int line) {
+ super(moduleName, line, null);
types = new ArrayList<TypeDefinition<?>>();
typedefs = new ArrayList<TypeDefinitionBuilder>();
}
-
public List<TypeDefinition<?>> getTypes() {
return types;
}
@Override
public void setDescription(final String description) {
- throw new YangParseException(line, "Can not set description to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set description to " + NAME);
}
@Override
public void setReference(final String reference) {
- throw new YangParseException(line, "Can not set reference to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set reference to " + NAME);
}
@Override
public void setStatus(final Status status) {
- throw new YangParseException(line, "Can not set status to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set status to " + NAME);
}
@Override
@Override
public void setAddedByUses(final boolean addedByUses) {
- throw new YangParseException(line, "Union type can not be added by uses.");
+ throw new YangParseException(moduleName, line, "Union type can not be added by uses.");
}
@Override
@Override
public void setRanges(List<RangeConstraint> ranges) {
- throw new YangParseException(line, "Can not set ranges to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set ranges to " + NAME);
}
@Override
@Override
public void setLengths(List<LengthConstraint> lengths) {
- throw new YangParseException(line, "Can not set lengths to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set lengths to " + NAME);
}
@Override
@Override
public void setPatterns(List<PatternConstraint> patterns) {
- throw new YangParseException(line, "Can not set patterns to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set patterns to " + NAME);
}
@Override
@Override
public void setFractionDigits(Integer fractionDigits) {
- throw new YangParseException(line, "Can not set fraction digits to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set fraction digits to " + NAME);
}
@Override
@Override
public void setDefaultValue(Object defaultValue) {
- throw new YangParseException(line, "Can not set default value to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set default value to " + NAME);
}
@Override
@Override
public void setUnits(String units) {
- throw new YangParseException(line, "Can not set units to " + NAME);
+ throw new YangParseException(moduleName, line, "Can not set units to " + NAME);
}
@Override
private QName nodeType;
private String nodeParameter;
- public UnknownSchemaNodeBuilder(final int line, final QName qname) {
- super(line, qname);
+ public UnknownSchemaNodeBuilder(final String moduleName, final int line, final QName qname) {
+ super(moduleName, line, qname);
instance = new UnknownSchemaNodeImpl(qname);
}
public UnknownSchemaNodeBuilder(UnknownSchemaNodeBuilder b) {
- super(b.getLine(), b.getQName());
+ super(b.getModuleName(), b.getLine(), b.getQName());
instance = new UnknownSchemaNodeImpl(qname);
schemaPath = b.getPath();
description = b.getDescription();
import org.opendaylight.controller.yang.model.api.SchemaPath;\r
import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;\r
import org.opendaylight.controller.yang.model.api.UsesNode;\r
+import org.opendaylight.controller.yang.parser.builder.api.AbstractBuilder;\r
import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;\r
import org.opendaylight.controller.yang.parser.builder.api.Builder;\r
import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder;\r
import org.opendaylight.controller.yang.parser.util.RefineHolder;\r
import org.opendaylight.controller.yang.parser.util.YangParseException;\r
\r
-public final class UsesNodeBuilderImpl implements UsesNodeBuilder {\r
+public final class UsesNodeBuilderImpl extends AbstractBuilder implements UsesNodeBuilder {\r
private boolean isBuilt;\r
private UsesNodeImpl instance;\r
- private final int line;\r
private DataNodeContainerBuilder parent;\r
private final String groupingName;\r
private SchemaPath groupingPath;\r
private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<AugmentationSchemaBuilder>();\r
private final List<SchemaNodeBuilder> refineBuilders = new ArrayList<SchemaNodeBuilder>();\r
private final List<RefineHolder> refines = new ArrayList<RefineHolder>();\r
- private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();\r
\r
- public UsesNodeBuilderImpl(final int line, final String groupingName) {\r
+ public UsesNodeBuilderImpl(final String moduleName, final int line, final String groupingName) {\r
+ super(moduleName, line);\r
this.groupingName = groupingName;\r
- this.line = line;\r
}\r
\r
public UsesNodeBuilderImpl(UsesNodeBuilder b) {\r
+ super(b.getModuleName(), b.getLine());\r
groupingName = b.getGroupingName();\r
- line = b.getLine();\r
parent = b.getParent();\r
groupingPath = b.getGroupingPath();\r
augmenting = b.isAugmenting();\r
return instance;\r
}\r
\r
- @Override\r
- public int getLine() {\r
- return line;\r
- }\r
-\r
@Override\r
public DataNodeContainerBuilder getParent() {\r
return parent;\r
@Override\r
public void setParent(Builder parent) {\r
if (!(parent instanceof DataNodeContainerBuilder)) {\r
- throw new YangParseException(line, "Unresolved parent of uses '" + groupingName + "'.");\r
+ throw new YangParseException(moduleName, line, "Unresolved parent of uses '" + groupingName + "'.");\r
}\r
this.parent = (DataNodeContainerBuilder) parent;\r
}\r
refines.add(refine);\r
}\r
\r
- @Override\r
- public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {\r
- return addedUnknownNodes;\r
- }\r
-\r
- @Override\r
- public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {\r
- addedUnknownNodes.add(unknownNode);\r
- }\r
-\r
@Override\r
public int hashCode() {\r
final int prime = 31;\r
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
}
// child nodes
- processUsesNode(usesNode, targetGrouping);
+ processUsesNode(module, usesNode, targetGrouping);
}
}
usesNode.setGroupingPath(targetGrouping.getPath());
for (RefineHolder refine : usesNode.getRefines()) {
final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingDefinition(
- targetGrouping, refine, module.getName());
+ targetGrouping, refine);
if (nodeToRefine instanceof GroupingMember) {
((GroupingMember) nodeToRefine).setAddedByUses(true);
}
usesNode.addRefineNode(nodeToRefine);
}
- processUsesNode(usesNode, targetGroupingBuilder);
+ processUsesNode(module, usesNode, targetGroupingBuilder);
}
}
}
}
/**
- * Add nodes defined in target grouping to current context.
+ * Add nodes defined in target grouping to current context. Refinement has
+ * to be already performed.
*
+ * @param module current module
* @param usesNode
* @param targetGrouping
*/
- private void processUsesNode(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
+ private void processUsesNode(final ModuleBuilder module, final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
List<SchemaNodeBuilder> refineNodes = usesNode.getRefineNodes();
DataNodeContainerBuilder parent = usesNode.getParent();
+ URI namespace = null;
+ Date revision = null;
+ String prefix = null;
+ if (parent instanceof ModuleBuilder || parent instanceof AugmentationSchemaBuilder) {
+ namespace = module.getNamespace();
+ revision = module.getRevision();
+ prefix = module.getPrefix();
+ } else {
+ QName parentQName = parent.getQName();
+ namespace = parentQName.getNamespace();
+ revision = parentQName.getRevision();
+ prefix = parentQName.getPrefix();
+ }
SchemaPath parentPath = parent.getPath();
for (DataSchemaNodeBuilder child : targetGrouping.getChildNodeBuilders()) {
if (child != null) {
// if node is refined, take it from refined nodes and continue
SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
if (refined != null) {
- refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
+ refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName(), namespace,
+ revision, prefix));
parent.addChildNode((DataSchemaNodeBuilder) refined);
continue;
}
}
if (newChild == null) {
- throw new YangParseException(usesNode.getLine(),
+ throw new YangParseException(usesNode.getModuleName(), usesNode.getLine(),
"Unknown member of target grouping while resolving uses node.");
}
((GroupingMember) newChild).setAddedByUses(true);
}
- newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName()));
+ newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision,
+ prefix));
parent.addChildNode(newChild);
}
}
for (GroupingBuilder g : targetGrouping.getGroupingBuilders()) {
GroupingBuilder newGrouping = new GroupingBuilderImpl(g);
newGrouping.setAddedByUses(true);
- newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName()));
+ newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace,
+ revision, prefix));
parent.addGrouping(newGrouping);
}
for (TypeDefinitionBuilder td : targetGrouping.getTypeDefinitionBuilders()) {
TypeDefinitionBuilder newType = new TypeDefinitionBuilderImpl(td);
newType.setAddedByUses(true);
- newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName()));
+ newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix));
parent.addTypedef(newType);
}
for (UsesNodeBuilder un : targetGrouping.getUses()) {
for (UnknownSchemaNodeBuilder un : targetGrouping.getUnknownNodeBuilders()) {
UnknownSchemaNodeBuilder newUn = new UnknownSchemaNodeBuilder(un);
newUn.setAddedByUses(true);
- newUn.setPath(createSchemaPath(parentPath, un.getQName().getLocalName()));
+ newUn.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix));
parent.addUnknownNodeBuilder(newUn);
}
}
private void processUsesNode(final UsesNodeBuilder usesNode, final GroupingDefinition targetGrouping) {
+ final String moduleName = usesNode.getModuleName();
final int line = usesNode.getLine();
List<SchemaNodeBuilder> refineNodes = usesNode.getRefineNodes();
DataNodeContainerBuilder parent = usesNode.getParent();
+ URI namespace = null;
+ Date revision = null;
+ String prefix = null;
+ if (parent instanceof ModuleBuilder) {
+ ModuleBuilder module = (ModuleBuilder) parent;
+ namespace = module.getNamespace();
+ revision = module.getRevision();
+ prefix = module.getPrefix();
+ } else {
+ QName parentQName = parent.getQName();
+ namespace = parentQName.getNamespace();
+ revision = parentQName.getRevision();
+ prefix = parentQName.getPrefix();
+ }
SchemaPath parentPath = parent.getPath();
for (DataSchemaNode child : targetGrouping.getChildNodes()) {
if (child != null) {
// if node is refined, take it from refined nodes and continue
SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
if (refined != null) {
- refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
+ refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName(), namespace,
+ revision, prefix));
parent.addChildNode((DataSchemaNodeBuilder) refined);
continue;
}
DataSchemaNodeBuilder newChild = null;
if (child instanceof AnyXmlSchemaNode) {
- newChild = createAnyXml((AnyXmlSchemaNode) child, line);
+ newChild = createAnyXml((AnyXmlSchemaNode) child, moduleName, line);
} else if (child instanceof ChoiceNode) {
- newChild = createChoice((ChoiceNode) child, line);
+ newChild = createChoice((ChoiceNode) child, moduleName, line);
} else if (child instanceof ContainerSchemaNode) {
- newChild = createContainer((ContainerSchemaNode) child, line);
+ newChild = createContainer((ContainerSchemaNode) child, moduleName, line);
} else if (child instanceof LeafListSchemaNode) {
- newChild = createLeafList((LeafListSchemaNode) child, line);
+ newChild = createLeafList((LeafListSchemaNode) child, moduleName, line);
} else if (child instanceof LeafSchemaNode) {
- newChild = createLeafBuilder((LeafSchemaNode) child, line);
+ newChild = createLeafBuilder((LeafSchemaNode) child, moduleName, line);
} else if (child instanceof ListSchemaNode) {
- newChild = createList((ListSchemaNode) child, line);
+ newChild = createList((ListSchemaNode) child, moduleName, line);
}
if (newChild == null) {
- throw new YangParseException(usesNode.getLine(),
+ throw new YangParseException(moduleName, line,
"Unknown member of target grouping while resolving uses node.");
}
if (newChild instanceof GroupingMember) {
((GroupingMember) newChild).setAddedByUses(true);
}
- newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName()));
+ newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision,
+ prefix));
parent.addChildNode(newChild);
}
}
for (GroupingDefinition g : targetGrouping.getGroupings()) {
- GroupingBuilder newGrouping = createGrouping(g, line);
+ GroupingBuilder newGrouping = createGrouping(g, moduleName, line);
newGrouping.setAddedByUses(true);
- newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName()));
+ newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace,
+ revision, prefix));
parent.addGrouping(newGrouping);
}
for (TypeDefinition<?> td : targetGrouping.getTypeDefinitions()) {
- TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, line);
+ TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, moduleName, line);
newType.setAddedByUses(true);
- newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName()));
+ newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix));
parent.addTypedef(newType);
}
for (UsesNode un : targetGrouping.getUses()) {
}
}
for (UnknownSchemaNode un : targetGrouping.getUnknownSchemaNodes()) {
- UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, line);
+ UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, moduleName, line);
newNode.setAddedByUses(true);
- newNode.setPath(createSchemaPath(parentPath, un.getQName().getLocalName()));
+ newNode.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix));
parent.addUnknownNodeBuilder(newNode);
}
}
SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, typeName);
moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
} else {
- type = parseTypeWithBody(moduleName, typeName, typeBody, actualPath, namespace, revision,
- yangModelPrefix, moduleBuilder.getActualNode());
+ type = parseTypeWithBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix,
+ moduleBuilder.getActualNode());
moduleBuilder.setType(type);
}
}
} else {
- type = parseUnknownTypeWithBody(moduleName, typeQName, typeBody, actualPath, namespace, revision, yangModelPrefix,
+ type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath, namespace, revision, yangModelPrefix,
moduleBuilder.getActualNode());
// add parent node of this type statement to dirty nodes
moduleBuilder.markActualNodeDirty();
exitLog("uses", actualPath.pop());
}
+ @Override public void enterUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+ final int line = ctx.getStart().getLine();
+ final String augmentPath = stringFromNode(ctx);
+ enterLog("augment", augmentPath, line);
+
+ AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath);
+
+ for (int i = 0; i < ctx.getChildCount(); i++) {
+ ParseTree child = ctx.getChild(i);
+ if (child instanceof Description_stmtContext) {
+ builder.setDescription(stringFromNode(child));
+ } else if (child instanceof Reference_stmtContext) {
+ builder.setReference(stringFromNode(child));
+ } else if (child instanceof Status_stmtContext) {
+ builder.setStatus(parseStatus((Status_stmtContext) child));
+ } else if (child instanceof When_stmtContext) {
+ builder.addWhenCondition(stringFromNode(child));
+ }
+ }
+
+ moduleBuilder.enterNode(builder);
+ actualPath.push(augmentPath);
+ }
+
+ @Override public void exitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+ moduleBuilder.exitNode();
+ exitLog("augment", actualPath.pop());
+ }
+
@Override
public void enterRefine_stmt(YangParser.Refine_stmtContext ctx) {
final String refineString = stringFromNode(ctx);
enterLog("refine", refineString, ctx.getStart().getLine());
- RefineHolder refine = parseRefine(ctx);
- moduleBuilder.addRefine(refine, actualPath);
+ RefineHolder refine = parseRefine(ctx, moduleName);
+ moduleBuilder.addRefine(refine);
moduleBuilder.enterNode(refine);
actualPath.push(refineString);
}
enterLog("notification", notificationName, line);
QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
- NotificationBuilder builder = moduleBuilder.addNotification(notificationQName, actualPath, line);
+ NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName);
moduleBuilder.enterNode(builder);
actualPath.push(notificationName);
QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, input);
- ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(path, rpcQName, line);
+ ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
moduleBuilder.enterNode(builder);
actualPath.push(input);
* type body context to parse
* @param path
* actual position in YANG model
+ * @param moduleName current module name
* @param namespace
* @param revision
* @param prefix
* @return List of EnumPair object parsed from given context
*/
private static List<EnumTypeDefinition.EnumPair> getEnumConstants(final Type_body_stmtsContext ctx,
- final List<String> path, final URI namespace, final Date revision, final String prefix) {
+ final List<String> path, final String moduleName, final URI namespace, final Date revision, final String prefix) {
List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<EnumTypeDefinition.EnumPair>();
for (int i = 0; i < ctx.getChildCount(); i++) {
for (int j = 0; j < enumSpecChild.getChildCount(); j++) {
ParseTree enumChild = enumSpecChild.getChild(j);
if (enumChild instanceof Enum_stmtContext) {
- EnumPair enumPair = createEnumPair((Enum_stmtContext) enumChild, highestValue, path, namespace,
+ EnumPair enumPair = createEnumPair((Enum_stmtContext) enumChild, highestValue, path, moduleName, namespace,
revision, prefix);
if (enumPair.getValue() > highestValue) {
highestValue = enumPair.getValue();
* current highest value in enumeration
* @param path
* actual position in YANG model
+ * @param moduleName
+ * current module name
* @param namespace
* @param revision
* @param prefix
* @return EnumPair object parsed from given context
*/
private static EnumTypeDefinition.EnumPair createEnumPair(final Enum_stmtContext ctx, final int highestValue,
- final List<String> path, final URI namespace, final Date revision, final String prefix) {
+ final List<String> path, final String moduleName, final URI namespace, final Date revision,
+ final String prefix) {
final String name = stringFromNode(ctx);
final QName qname = new QName(namespace, revision, prefix, name);
Integer value = null;
value = highestValue + 1;
}
if (value < -2147483648 || value > 2147483647) {
- throw new YangParseException(ctx.getStart().getLine(), "Error on enum '" + name
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Error on enum '" + name
+ "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: " + value);
}
* type body context to parse
* @return List of RangeConstraint created from this context
*/
- private static List<RangeConstraint> getRangeConstraints(final Type_body_stmtsContext ctx) {
+ private static List<RangeConstraint> getRangeConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
List<RangeConstraint> rangeConstraints = Collections.emptyList();
outer: for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree numRestrChild = ctx.getChild(i);
for (int j = 0; j < numRestrChild.getChildCount(); j++) {
ParseTree rangeChild = numRestrChild.getChild(j);
if (rangeChild instanceof Range_stmtContext) {
- rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild);
+ rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
break outer;
}
}
* range context to parse
* @return List of RangeConstraints parsed from this context
*/
- private static List<RangeConstraint> parseRangeConstraints(final Range_stmtContext ctx) {
+ private static List<RangeConstraint> parseRangeConstraints(final Range_stmtContext ctx, final String moduleName) {
final int line = ctx.getStart().getLine();
List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();
String description = null;
Number min;
Number max;
if (splittedRangeDef.length == 1) {
- min = max = parseNumberConstraintValue(splittedRangeDef[0], line);
+ min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
} else {
- min = parseNumberConstraintValue(splittedRangeDef[0], line);
- max = parseNumberConstraintValue(splittedRangeDef[1], line);
+ min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+ max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
}
RangeConstraint range = BaseConstraints.rangeConstraint(min, max, description, reference);
rangeConstraints.add(range);
* type body context to parse
* @return List of LengthConstraint created from this context
*/
- private static List<LengthConstraint> getLengthConstraints(final Type_body_stmtsContext ctx) {
+ private static List<LengthConstraint> getLengthConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
List<LengthConstraint> lengthConstraints = Collections.emptyList();
outer: for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree stringRestrChild = ctx.getChild(i);
for (int j = 0; j < stringRestrChild.getChildCount(); j++) {
ParseTree lengthChild = stringRestrChild.getChild(j);
if (lengthChild instanceof Length_stmtContext) {
- lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild);
+ lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
break outer;
}
}
* length context to parse
* @return List of LengthConstraints parsed from this context
*/
- private static List<LengthConstraint> parseLengthConstraints(final Length_stmtContext ctx) {
+ private static List<LengthConstraint> parseLengthConstraints(final Length_stmtContext ctx, final String moduleName) {
final int line = ctx.getStart().getLine();
List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();
String description = null;
Number min;
Number max;
if (splittedRangeDef.length == 1) {
- min = max = parseNumberConstraintValue(splittedRangeDef[0], line);
+ min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
} else {
- min = parseNumberConstraintValue(splittedRangeDef[0], line);
- max = parseNumberConstraintValue(splittedRangeDef[1], line);
+ min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+ max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
}
LengthConstraint range = BaseConstraints.lengthConstraint(min, max, description, reference);
lengthConstraints.add(range);
* @return wrapper object of primitive java type or UnknownBoundaryNumber if
* type is one of special YANG values 'min' or 'max'
*/
- private static Number parseNumberConstraintValue(final String value, final int line) {
+ private static Number parseNumberConstraintValue(final String value, final String moduleName, final int line) {
Number result = null;
if ("min".equals(value) || "max".equals(value)) {
result = new UnknownBoundaryNumber(value);
try {
result = Long.valueOf(value);
} catch (NumberFormatException e) {
- throw new YangParseException(line, "Unable to parse range value '" + value + "'.", e);
+ throw new YangParseException(moduleName, line, "Unable to parse range value '" + value + "'.", e);
}
}
return result;
* type body context to parse
* @param actualPath
* current position in YANG model
+ * @param moduleName current module name
* @param namespace
* @param revision
* @param prefix
* @return List of Bit objects created from this context
*/
private static List<BitsTypeDefinition.Bit> getBits(Type_body_stmtsContext ctx, List<String> actualPath,
- URI namespace, Date revision, String prefix) {
+ String moduleName, URI namespace, Date revision, String prefix) {
final List<BitsTypeDefinition.Bit> bits = new ArrayList<BitsTypeDefinition.Bit>();
for (int j = 0; j < ctx.getChildCount(); j++) {
ParseTree bitsSpecChild = ctx.getChild(j);
for (int k = 0; k < bitsSpecChild.getChildCount(); k++) {
ParseTree bitChild = bitsSpecChild.getChild(k);
if (bitChild instanceof Bit_stmtContext) {
- Bit bit = parseBit((Bit_stmtContext) bitChild, highestPosition, actualPath, namespace,
+ Bit bit = parseBit((Bit_stmtContext) bitChild, highestPosition, actualPath, moduleName, namespace,
revision, prefix);
if (bit.getPosition() > highestPosition) {
highestPosition = bit.getPosition();
* current highest position in bits type
* @param actualPath
* current position in YANG model
+ * @param moduleName current module name
* @param namespace
* @param revision
* @param prefix
* @return Bit object parsed from this context
*/
private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx, long highestPosition,
- List<String> actualPath, final URI namespace, final Date revision, final String prefix) {
+ List<String> actualPath, final String moduleName, final URI namespace, final Date revision, final String prefix) {
String name = stringFromNode(ctx);
final QName qname = new QName(namespace, revision, prefix, name);
Long position = null;
position = highestPosition + 1;
}
if (position < 0 || position > 4294967295L) {
- throw new YangParseException(ctx.getStart().getLine(), "Error on bit '" + name
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Error on bit '" + name
+ "': the position value MUST be in the range 0 to 4294967295");
}
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Config_stmtContext) {
- config = parseConfig((Config_stmtContext) child);
+ config = parseConfig((Config_stmtContext) child, moduleName);
break;
}
}
* Parse config statement.
*
* @param ctx
- * config context to parse.
+ * config context to parse
+ * @param moduleName current module name
* @return true if given context contains string 'true', false otherwise
*/
- private static Boolean parseConfig(final Config_stmtContext ctx) {
+ private static Boolean parseConfig(final Config_stmtContext ctx, final String moduleName) {
Boolean result = null;
if (ctx != null) {
for (int i = 0; i < ctx.getChildCount(); ++i) {
result = false;
break;
} else {
- throw new YangParseException(ctx.getStart().getLine(),
+ throw new YangParseException(moduleName, ctx.getStart().getLine(),
"Failed to parse 'config' statement value: '" + value + "'.");
}
}
/**
* Parse type body and create UnknownType definition.
*
- * @param moduleName
- * name of current module
* @param typedefQName
* qname of current type
* @param ctx
* @param parent
* @return UnknownType object with constraints from parsed type body
*/
- public static TypeDefinition<?> parseUnknownTypeWithBody(final String moduleName, final QName typedefQName,
+ public static TypeDefinition<?> parseUnknownTypeWithBody(final QName typedefQName,
final Type_body_stmtsContext ctx, final List<String> actualPath, final URI namespace, final Date revision,
final String prefix, final Builder parent) {
+ String moduleName = parent.getModuleName();
String typeName = typedefQName.getLocalName();
UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName);
if (ctx != null) {
- List<RangeConstraint> rangeStatements = getRangeConstraints(ctx);
- List<LengthConstraint> lengthStatements = getLengthConstraints(ctx);
+ List<RangeConstraint> rangeStatements = getRangeConstraints(ctx, moduleName);
+ List<LengthConstraint> lengthStatements = getLengthConstraints(ctx, moduleName);
List<PatternConstraint> patternStatements = getPatternConstraint(ctx);
Integer fractionDigits = getFractionDigits(ctx, moduleName);
/**
* Create TypeDefinition object based on given type name and type body.
*
- * @param moduleName
- * current module name
* @param typeName
* name of type
* @param typeBody
* parent builder
* @return TypeDefinition object based on parsed values.
*/
- public static TypeDefinition<?> parseTypeWithBody(final String moduleName, final String typeName,
+ public static TypeDefinition<?> parseTypeWithBody(final String typeName,
final Type_body_stmtsContext typeBody, final List<String> actualPath, final URI namespace,
final Date revision, final String prefix, final Builder parent) {
+ final String moduleName = parent.getModuleName();
final int line = typeBody.getStart().getLine();
TypeDefinition<?> baseType = null;
Integer fractionDigits = getFractionDigits(typeBody, moduleName);
- List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody);
+ List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody, moduleName);
List<PatternConstraint> patternStatements = getPatternConstraint(typeBody);
- List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody);
+ List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody, moduleName);
TypeConstraints constraints = new TypeConstraints(moduleName, line);
constraints.addFractionDigits(fractionDigits);
constraints.addRanges(uintType.getRangeStatements());
baseType = uintType;
} else if ("enumeration".equals(typeName)) {
- List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, namespace,
+ List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, moduleName, namespace,
revision, prefix);
return new EnumerationType(baseTypePathFinal, enumConstants);
} else if ("string".equals(typeName)) {
constraints.addLengths(stringType.getLengthStatements());
baseType = stringType;
} else if ("bits".equals(typeName)) {
- return new BitsType(baseTypePathFinal, getBits(typeBody, actualPath, namespace, revision, prefix));
+ return new BitsType(baseTypePathFinal, getBits(typeBody, actualPath, moduleName, namespace, revision, prefix));
} else if ("leafref".equals(typeName)) {
final String path = parseLeafrefPath(typeBody);
final boolean absolute = path.startsWith("/");
for (int i = 0; i < ctx.getChildCount(); ++i) {
final ParseTree childNode = ctx.getChild(i);
if (childNode instanceof Max_elements_stmtContext) {
- Integer max = parseMaxElements((Max_elements_stmtContext) childNode);
+ Integer max = parseMaxElements((Max_elements_stmtContext) childNode, constraints.getModuleName());
constraints.setMaxElements(max);
} else if (childNode instanceof Min_elements_stmtContext) {
- Integer min = parseMinElements((Min_elements_stmtContext) childNode);
+ Integer min = parseMinElements((Min_elements_stmtContext) childNode, constraints.getModuleName());
constraints.setMinElements(min);
} else if (childNode instanceof Must_stmtContext) {
MustDefinition must = parseMust((Must_stmtContext) childNode);
}
}
- private static Integer parseMinElements(Min_elements_stmtContext ctx) {
+ private static Integer parseMinElements(Min_elements_stmtContext ctx, String moduleName) {
Integer result = null;
try {
for (int i = 0; i < ctx.getChildCount(); i++) {
}
return result;
} catch (Exception e) {
- throw new YangParseException(ctx.getStart().getLine(), "Failed to parse min-elements.", e);
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Failed to parse min-elements.", e);
}
}
- private static Integer parseMaxElements(Max_elements_stmtContext ctx) {
+ private static Integer parseMaxElements(Max_elements_stmtContext ctx, String moduleName) {
Integer result = null;
try {
for (int i = 0; i < ctx.getChildCount(); i++) {
}
return result;
} catch (Exception e) {
- throw new YangParseException(ctx.getStart().getLine(), "Failed to parse max-elements.", e);
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Failed to parse max-elements.", e);
}
}
* refine statement
* @return RefineHolder object representing this refine statement
*/
- public static RefineHolder parseRefine(Refine_stmtContext refineCtx) {
+ public static RefineHolder parseRefine(Refine_stmtContext refineCtx, String moduleName) {
final String refineTarget = stringFromNode(refineCtx);
- final RefineHolder refine = new RefineHolder(refineCtx.getStart().getLine(), refineTarget);
+ final RefineHolder refine = new RefineHolder(moduleName, refineCtx.getStart().getLine(), refineTarget);
for (int i = 0; i < refineCtx.getChildCount(); i++) {
ParseTree refinePom = refineCtx.getChild(i);
if (refinePom instanceof Refine_pomContext) {
String reference = stringFromNode(refineArg);
refine.setReference(reference);
} else if (refineArg instanceof Config_stmtContext) {
- Boolean config = parseConfig((Config_stmtContext) refineArg);
+ Boolean config = parseConfig((Config_stmtContext) refineArg, refine.getModuleName());
refine.setConfiguration(config);
}
}
MustDefinition must = parseMust((Must_stmtContext) refineArg);
refine.setMust(must);
} else if (refineArg instanceof Max_elements_stmtContext) {
- Integer max = parseMaxElements((Max_elements_stmtContext) refineArg);
+ Integer max = parseMaxElements((Max_elements_stmtContext) refineArg, refine.getModuleName());
refine.setMaxElements(max);
} else if (refineArg instanceof Min_elements_stmtContext) {
- Integer min = parseMinElements((Min_elements_stmtContext) refineArg);
+ Integer min = parseMinElements((Min_elements_stmtContext) refineArg, refine.getModuleName());
refine.setMinElements(min);
}
}
MustDefinition must = parseMust((Must_stmtContext) refineArg);
refine.setMust(must);
} else if (refineArg instanceof Max_elements_stmtContext) {
- Integer max = parseMaxElements((Max_elements_stmtContext) refineArg);
+ Integer max = parseMaxElements((Max_elements_stmtContext) refineArg, refine.getModuleName());
refine.setMaxElements(max);
} else if (refineArg instanceof Min_elements_stmtContext) {
- Integer min = parseMinElements((Min_elements_stmtContext) refineArg);
+ Integer min = parseMinElements((Min_elements_stmtContext) refineArg, refine.getModuleName());
refine.setMinElements(min);
}
}
*/
package org.opendaylight.controller.yang.parser.util;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl;
import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
+import org.opendaylight.controller.yang.parser.builder.impl.IdentityrefTypeBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
* @param name
* @return
*/
- public static SchemaPath createSchemaPath(SchemaPath schemaPath, String name) {
- List<QName> path = new ArrayList<QName>(schemaPath.getPath());
- QName last = path.get(path.size() - 1);
- QName newQName = new QName(last.getNamespace(), last.getRevision(), last.getPrefix(), name);
+ public static SchemaPath createSchemaPath(SchemaPath schemaPath, String name, URI namespace, Date revision, String prefix) {
+ List<QName> path = new ArrayList<QName>();
+ if(schemaPath != null) {
+ path.addAll(schemaPath.getPath());
+ }
+ QName newQName = new QName(namespace, revision, prefix, name);
path.add(newQName);
- return new SchemaPath(path, schemaPath.isAbsolute());
+ boolean abs = schemaPath == null ? true : schemaPath.isAbsolute();
+ return new SchemaPath(path, abs);
}
/**
}
}
correctAugmentChildPath(builder, target.getPath());
- target.addChildNode(builder);
+ target.addCase(builder);
}
}
* line in module
* @return builder object from leaf
*/
- public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, int line) {
- final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(leaf.getQName(), leaf.getPath(), line);
+ public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, String moduleName, int line) {
+ final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(moduleName, line, leaf.getQName(),
+ leaf.getPath());
convertDataSchemaNode(leaf, builder);
builder.setConfiguration(leaf.isConfiguration());
final TypeDefinition<?> type = leaf.getType();
return builder;
}
- public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, int line) {
- final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(line, container.getQName(),
- container.getPath());
+ public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, String moduleName, int line) {
+ final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(moduleName, line,
+ container.getQName(), container.getPath());
convertDataSchemaNode(container, builder);
builder.setConfiguration(container.isConfiguration());
builder.setUnknownNodes(container.getUnknownSchemaNodes());
return builder;
}
- public static ListSchemaNodeBuilder createList(ListSchemaNode list, int line) {
- ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(line, list.getQName(), list.getPath());
+ public static ListSchemaNodeBuilder createList(ListSchemaNode list, String moduleName, int line) {
+ ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(moduleName, line, list.getQName(), list.getPath());
convertDataSchemaNode(list, builder);
builder.setConfiguration(list.isConfiguration());
builder.setUnknownNodes(list.getUnknownSchemaNodes());
return builder;
}
- public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, int line) {
- final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(line, leafList.getQName(),
+ public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, String moduleName, int line) {
+ final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(moduleName, line, leafList.getQName(),
leafList.getPath());
convertDataSchemaNode(leafList, builder);
builder.setConfiguration(leafList.isConfiguration());
return builder;
}
- public static ChoiceBuilder createChoice(ChoiceNode choice, int line) {
- final ChoiceBuilder builder = new ChoiceBuilder(line, choice.getQName());
+ public static ChoiceBuilder createChoice(ChoiceNode choice, String moduleName, int line) {
+ final ChoiceBuilder builder = new ChoiceBuilder(moduleName, line, choice.getQName());
convertDataSchemaNode(choice, builder);
builder.setConfiguration(choice.isConfiguration());
builder.setCases(choice.getCases());
return builder;
}
- public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, int line) {
- final AnyXmlBuilder builder = new AnyXmlBuilder(line, anyxml.getQName(), anyxml.getPath());
+ public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, String moduleName, int line) {
+ final AnyXmlBuilder builder = new AnyXmlBuilder(moduleName, line, anyxml.getQName(), anyxml.getPath());
convertDataSchemaNode(anyxml, builder);
builder.setConfiguration(anyxml.isConfiguration());
builder.setUnknownNodes(anyxml.getUnknownSchemaNodes());
return builder;
}
- public static GroupingBuilder createGrouping(GroupingDefinition grouping, int line) {
- final GroupingBuilderImpl builder = new GroupingBuilderImpl(grouping.getQName(), line);
+ public static GroupingBuilder createGrouping(GroupingDefinition grouping, String moduleName, int line) {
+ final GroupingBuilderImpl builder = new GroupingBuilderImpl(moduleName, line, grouping.getQName());
builder.setPath(grouping.getPath());
builder.setChildNodes(grouping.getChildNodes());
builder.setGroupings(grouping.getGroupings());
return builder;
}
- public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, int line) {
- final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typedef.getQName(), line);
+ public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, String moduleName, int line) {
+ final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(moduleName, line, typedef.getQName());
builder.setPath(typedef.getPath());
builder.setDefaultValue(typedef.getDefaultValue());
builder.setUnits(typedef.getUnits());
return builder;
}
- public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, int line) {
- final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(line, unknownNode.getQName());
+ public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, String moduleName,
+ int line) {
+ final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(moduleName, line, unknownNode.getQName());
builder.setPath(unknownNode.getPath());
builder.setUnknownNodes(unknownNode.getUnknownSchemaNodes());
builder.setDescription(unknownNode.getDescription());
module.augmentResolved();
} else {
throw new YangParseException(module.getName(), line, "Target of type " + node.getClass()
- + " can not be augmented.");
+ + " cannot be augmented.");
}
}
tc.addRanges(oldExtendedType.getRanges());
final TypeConstraints constraints = findConstraintsFromTypeBuilder(newBaseType, tc, modules, module, null);
- final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line);
+ final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
+ oldExtendedType.getQName());
newType.setTypedef(newBaseType);
newType.setPath(oldExtendedType.getPath());
newType.setDescription(oldExtendedType.getDescription());
final TypeConstraints tc = new TypeConstraints(module.getName(), line);
final TypeConstraints constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
- final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line);
+ final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
+ oldExtendedType.getQName());
newType.setType(newBaseType);
newType.setPath(oldExtendedType.getPath());
newType.setDescription(oldExtendedType.getDescription());
final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
final ModuleBuilder builder, final SchemaContext context) {
- // union type cannot be restricted
- if (nodeToResolve instanceof UnionTypeBuilder) {
+ // union and identityref types cannot be restricted
+ if (nodeToResolve instanceof UnionTypeBuilder || nodeToResolve instanceof IdentityrefTypeBuilder) {
return constraints;
}
*/
package org.opendaylight.controller.yang.parser.util;
-import java.util.ArrayList;
-import java.util.List;
-
import org.opendaylight.controller.yang.model.api.MustDefinition;
-import org.opendaylight.controller.yang.parser.builder.api.Builder;
-import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.AbstractBuilder;
-public final class RefineHolder implements Builder {
- private Builder parent;
- private final int line;
+public final class RefineHolder extends AbstractBuilder {
private final String name;
private String defaultStr;
private String description;
private MustDefinition must;
private Integer minElements;
private Integer maxElements;
- private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
- public RefineHolder(final int line, final String name) {
+ public RefineHolder(final String moduleName, final int line, final String name) {
+ super(moduleName, line);
this.name = name;
- this.line = line;
- }
-
- @Override
- public int getLine() {
- return line;
- }
-
- @Override
- public Builder getParent() {
- return parent;
- }
-
- @Override
- public void setParent(final Builder parent) {
- this.parent = parent;
}
public String getDefaultStr() {
return name;
}
- @Override
- public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
- return addedUnknownNodes;
- }
-
- @Override
- public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
- addedUnknownNodes.add(unknownNode);
- }
-
@Override
public Object build() {
return null;
@Override
public String toString() {
- return "revine " + name;
+ return "refine " + name;
}
}
* grouping which should contains node to refine
* @param refine
* refine object containing informations about refine
- * @param moduleName
- * current module name
* @return
*/
public static SchemaNodeBuilder getRefineNodeFromGroupingDefinition(final GroupingDefinition grouping,
- final RefineHolder refine, final String moduleName) {
- SchemaNodeBuilder result = null;
+ final RefineHolder refine) {
+ final String moduleName = refine.getModuleName();
final int line = refine.getLine();
+ SchemaNodeBuilder result = null;
final Object lookedUpNode = findRefineTargetNode(grouping, refine.getName());
if (lookedUpNode instanceof LeafSchemaNode) {
- result = createLeafBuilder((LeafSchemaNode) lookedUpNode, line);
+ result = createLeafBuilder((LeafSchemaNode) lookedUpNode, moduleName, line);
} else if (lookedUpNode instanceof ContainerSchemaNode) {
- result = createContainer((ContainerSchemaNode) lookedUpNode, line);
+ result = createContainer((ContainerSchemaNode) lookedUpNode, moduleName, line);
} else if (lookedUpNode instanceof ListSchemaNode) {
- result = createList((ListSchemaNode) lookedUpNode, line);
+ result = createList((ListSchemaNode) lookedUpNode, moduleName, line);
} else if (lookedUpNode instanceof LeafListSchemaNode) {
- result = createLeafList((LeafListSchemaNode) lookedUpNode, line);
+ result = createLeafList((LeafListSchemaNode) lookedUpNode, moduleName, line);
} else if (lookedUpNode instanceof ChoiceNode) {
- result = createChoice((ChoiceNode) lookedUpNode, line);
+ result = createChoice((ChoiceNode) lookedUpNode, moduleName, line);
} else if (lookedUpNode instanceof AnyXmlSchemaNode) {
- result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, line);
+ result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, moduleName, line);
} else if (lookedUpNode instanceof GroupingDefinition) {
- result = createGrouping((GroupingDefinition) lookedUpNode, line);
+ result = createGrouping((GroupingDefinition) lookedUpNode, moduleName, line);
} else if (lookedUpNode instanceof TypeDefinition) {
- result = createTypedef((ExtendedType) lookedUpNode, line);
+ result = createTypedef((ExtendedType) lookedUpNode, moduleName, line);
} else {
throw new YangParseException(moduleName, line, "Target '" + refine.getName() + "' can not be refined");
}
return result;
}
- public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine, int line) {
+ public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine) {
String defaultStr = refine.getDefaultStr();
Boolean mandatory = refine.isMandatory();
MustDefinition must = refine.getMust();
* refine object containing information about refine process
*/
public static void checkRefine(SchemaNodeBuilder node, RefineHolder refine) {
- String name = node.getQName().getLocalName();
+ String moduleName = refine.getModuleName();
int line = refine.getLine();
+ String name = node.getQName().getLocalName();
String defaultStr = refine.getDefaultStr();
Boolean mandatory = refine.isMandatory();
Integer max = refine.getMaxElements();
if (node instanceof AnyXmlBuilder) {
- checkRefineDefault(node, defaultStr, line);
- checkRefinePresence(node, presence, line);
- checkRefineMinMax(name, line, min, max);
+ checkRefineDefault(node, defaultStr, moduleName, line);
+ checkRefinePresence(node, presence, moduleName, line);
+ checkRefineMinMax(name, min, max, moduleName, line);
} else if (node instanceof ChoiceBuilder) {
- checkRefinePresence(node, presence, line);
- checkRefineMust(node, must, line);
- checkRefineMinMax(name, line, min, max);
+ checkRefinePresence(node, presence, moduleName, line);
+ checkRefineMust(node, must, moduleName, line);
+ checkRefineMinMax(name, min, max, moduleName, line);
} else if (node instanceof ContainerSchemaNodeBuilder) {
- checkRefineDefault(node, defaultStr, line);
- checkRefineMandatory(node, mandatory, line);
- checkRefineMust(node, must, line);
- checkRefineMinMax(name, line, min, max);
+ checkRefineDefault(node, defaultStr, moduleName, line);
+ checkRefineMandatory(node, mandatory, moduleName, line);
+ checkRefineMust(node, must, moduleName, line);
+ checkRefineMinMax(name, min, max, moduleName, line);
} else if (node instanceof LeafSchemaNodeBuilder) {
- checkRefinePresence(node, presence, line);
- checkRefineMinMax(name, line, min, max);
+ checkRefinePresence(node, presence, moduleName, line);
+ checkRefineMinMax(name, min, max, moduleName, line);
} else if (node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder) {
- checkRefineDefault(node, defaultStr, line);
- checkRefinePresence(node, presence, line);
- checkRefineMandatory(node, mandatory, line);
+ checkRefineDefault(node, defaultStr, moduleName, line);
+ checkRefinePresence(node, presence, moduleName, line);
+ checkRefineMandatory(node, mandatory, moduleName, line);
} else if (node instanceof GroupingBuilder || node instanceof TypeDefinitionBuilder
|| node instanceof UsesNodeBuilder) {
- checkRefineDefault(node, defaultStr, line);
- checkRefinePresence(node, presence, line);
- checkRefineMandatory(node, mandatory, line);
- checkRefineMust(node, must, line);
- checkRefineMinMax(name, line, min, max);
+ checkRefineDefault(node, defaultStr, moduleName, line);
+ checkRefinePresence(node, presence, moduleName, line);
+ checkRefineMandatory(node, mandatory, moduleName, line);
+ checkRefineMust(node, must, moduleName, line);
+ checkRefineMinMax(name, min, max, moduleName, line);
}
}
- private static void checkRefineDefault(SchemaNodeBuilder node, String defaultStr, int line) {
+ private static void checkRefineDefault(SchemaNodeBuilder node, String defaultStr, String moduleName, int line) {
if (defaultStr != null) {
- throw new YangParseException(line, "Can not refine 'default' for '" + node.getQName().getLocalName() + "'.");
+ throw new YangParseException(moduleName, line, "Can not refine 'default' for '"
+ + node.getQName().getLocalName() + "'.");
}
}
- private static void checkRefineMandatory(SchemaNodeBuilder node, Boolean mandatory, int line) {
+ private static void checkRefineMandatory(SchemaNodeBuilder node, Boolean mandatory, String moduleName, int line) {
if (mandatory != null) {
- throw new YangParseException(line, "Can not refine 'mandatory' for '" + node.getQName().getLocalName()
- + "'.");
+ throw new YangParseException(moduleName, line, "Can not refine 'mandatory' for '"
+ + node.getQName().getLocalName() + "'.");
}
}
- private static void checkRefinePresence(SchemaNodeBuilder node, Boolean presence, int line) {
+ private static void checkRefinePresence(SchemaNodeBuilder node, Boolean presence, String moduleName, int line) {
if (presence != null) {
- throw new YangParseException(line, "Can not refine 'presence' for '" + node.getQName().getLocalName()
- + "'.");
+ throw new YangParseException(moduleName, line, "Can not refine 'presence' for '"
+ + node.getQName().getLocalName() + "'.");
}
}
- private static void checkRefineMust(SchemaNodeBuilder node, MustDefinition must, int line) {
+ private static void checkRefineMust(SchemaNodeBuilder node, MustDefinition must, String moduleName, int line) {
if (must != null) {
- throw new YangParseException(line, "Can not refine 'must' for '" + node.getQName().getLocalName() + "'.");
+ throw new YangParseException(moduleName, line, "Can not refine 'must' for '"
+ + node.getQName().getLocalName() + "'.");
}
}
- private static void checkRefineMinMax(String refineTargetName, int refineLine, Integer min, Integer max) {
+ private static void checkRefineMinMax(String refineTargetName, Integer min, Integer max, String moduleName, int line) {
if (min != null || max != null) {
- throw new YangParseException(refineLine, "Can not refine 'min-elements' or 'max-elements' for '"
+ throw new YangParseException(moduleName, line, "Can not refine 'min-elements' or 'max-elements' for '"
+ refineTargetName + "'.");
}
}
* node to refine
* @param refine
* refine object containing information about refine process
- * @param line
- * current line in yang model
*/
- public static void refineDefault(final Builder node, final RefineHolder refine, final int line) {
+ public static void refineDefault(final Builder node, final RefineHolder refine) {
+ final String moduleName = refine.getModuleName();
+ final int line = refine.getLine();
Class<? extends Builder> cls = node.getClass();
String description = refine.getDescription();
Method method = cls.getDeclaredMethod("setDescription", String.class);
method.invoke(node, description);
} catch (Exception e) {
- throw new YangParseException(line, "Cannot refine description in " + cls.getName(), e);
+ throw new YangParseException(moduleName, line, "Cannot refine description in " + cls.getName(), e);
}
}
Method method = cls.getDeclaredMethod("setReference", String.class);
method.invoke(node, reference);
} catch (Exception e) {
- throw new YangParseException(line, "Cannot refine reference in " + cls.getName(), e);
+ throw new YangParseException(moduleName, line, "Cannot refine reference in " + cls.getName(), e);
}
}
Method method = cls.getDeclaredMethod("setConfiguration", Boolean.class);
method.invoke(node, config);
} catch (Exception e) {
- throw new YangParseException(line, "Cannot refine config in " + cls.getName(), e);
+ throw new YangParseException(moduleName, line, "Cannot refine config in " + cls.getName(), e);
}
}
}
*/
public static void performRefine(SchemaNodeBuilder nodeToRefine, RefineHolder refine, int line) {
checkRefine(nodeToRefine, refine);
- refineDefault(nodeToRefine, refine, line);
+ refineDefault(nodeToRefine, refine);
if (nodeToRefine instanceof LeafSchemaNodeBuilder) {
- refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine, line);
+ refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine);
} else if (nodeToRefine instanceof ContainerSchemaNodeBuilder) {
refineContainer((ContainerSchemaNodeBuilder) nodeToRefine, refine, line);
} else if (nodeToRefine instanceof ListSchemaNodeBuilder) {
for (RangeConstraint range : typeRange) {
if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
- throw new YangParseException(line, "Unresolved range constraints");
+ throw new YangParseException(moduleName, line, "Unresolved range constraints");
}
final long min = range.getMin().longValue();
final long max = range.getMax().longValue();
for (RangeConstraint range : typeRange) {
if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
- throw new YangParseException(line, "Unresolved range constraints");
+ throw new YangParseException(moduleName, line, "Unresolved range constraints");
}
final long min = range.getMin().longValue();
final long max = range.getMax().longValue();
for (LengthConstraint length : typeLength) {
if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
- throw new YangParseException(line, "Unresolved length constraints");
+ throw new YangParseException(moduleName, line, "Unresolved length constraints");
}
final long min = length.getMin().longValue();
final long max = length.getMax().longValue();
for (LengthConstraint length : typeLength) {
if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
- throw new YangParseException(line, "Unresolved length constraints");
+ throw new YangParseException(moduleName, line, "Unresolved length constraints");
}
final long min = length.getMin().longValue();
final long max = length.getMax().longValue();
package org.opendaylight.controller.yang.parser.util;
public class YangParseException extends RuntimeException {
-
private static final long serialVersionUID = 1239548963471793178L;
public YangParseException(final String errorMsg) {
super(errorMsg, exception);
}
- public YangParseException(final int line, final String errorMsg) {
- super("Error on line " + line + ": " + errorMsg);
- }
-
- public YangParseException(final int line, final String errorMsg,
- final Exception exception) {
- super("Error on line " + line + ": " + errorMsg, exception);
- }
-
public YangParseException(final String moduleName, final int line,
final String errorMsg) {
- super("Error in module '" + moduleName + "' on line " + line + ": "
+ super("Error in module '" + moduleName + "' at line " + line + ": "
+ errorMsg);
}
public YangParseException(final String moduleName, final int line,
final String errorMsg, final Exception exception) {
- super("Error in module '" + moduleName + "' on line " + line + ": "
+ super("Error in module '" + moduleName + "' at line " + line + ": "
+ errorMsg, exception);
}
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;
import org.opendaylight.controller.yang.model.api.ChoiceNode;
import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
import org.opendaylight.controller.yang.model.api.DataSchemaNode;
assertFalse(node_u.equals(node_g));
}
+ @Test
+ public void testUsesUnderModule() {
+ // suffix _u = added by uses
+ // suffix _g = defined in grouping
+
+ Module testModule = TestUtils.findModule(modules, "custom");
+
+ // get grouping
+ Set<GroupingDefinition> groupings = testModule.getGroupings();
+ assertEquals(1, groupings.size());
+ GroupingDefinition grouping = groupings.iterator().next();
+
+ // get node containing uses
+ Module destination = TestUtils.findModule(modules, "nodes");
+
+ // check uses
+ Set<UsesNode> uses = destination.getUses();
+ assertEquals(1, uses.size());
+
+ // check uses process
+ AnyXmlSchemaNode data_u = (AnyXmlSchemaNode) destination.getDataChildByName("data");
+ assertNotNull(data_u);
+ assertTrue(data_u.isAddedByUses());
+
+ AnyXmlSchemaNode data_g = (AnyXmlSchemaNode) grouping.getDataChildByName("data");
+ assertNotNull(data_g);
+ assertFalse(data_g.isAddedByUses());
+ assertFalse(data_u.equals(data_g));
+
+ ChoiceNode how_u = (ChoiceNode) destination.getDataChildByName("how");
+ assertNotNull(how_u);
+ assertTrue(how_u.isAddedByUses());
+
+ ChoiceNode how_g = (ChoiceNode) grouping.getDataChildByName("how");
+ assertNotNull(how_g);
+ assertFalse(how_g.isAddedByUses());
+ assertFalse(how_u.equals(how_g));
+
+ LeafSchemaNode address_u = (LeafSchemaNode) destination.getDataChildByName("address");
+ assertNotNull(address_u);
+ assertNull(address_u.getDefault());
+ assertEquals("Target IP address", address_u.getDescription());
+ assertNull(address_u.getReference());
+ assertTrue(address_u.isConfiguration());
+ assertTrue(address_u.isAddedByUses());
+
+ LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName("address");
+ assertNotNull(address_g);
+ assertFalse(address_g.isAddedByUses());
+ assertNull(address_g.getDefault());
+ assertEquals("Target IP address", address_g.getDescription());
+ assertNull(address_g.getReference());
+ assertTrue(address_g.isConfiguration());
+ assertFalse(address_u.equals(address_g));
+
+ ContainerSchemaNode port_u = (ContainerSchemaNode) destination.getDataChildByName("port");
+ assertNotNull(port_u);
+ assertTrue(port_u.isAddedByUses());
+
+ ContainerSchemaNode port_g = (ContainerSchemaNode) grouping.getDataChildByName("port");
+ assertNotNull(port_g);
+ assertFalse(port_g.isAddedByUses());
+ assertFalse(port_u.equals(port_g));
+
+ ListSchemaNode addresses_u = (ListSchemaNode) destination.getDataChildByName("addresses");
+ assertNotNull(addresses_u);
+ assertTrue(addresses_u.isAddedByUses());
+
+ ListSchemaNode addresses_g = (ListSchemaNode) grouping.getDataChildByName("addresses");
+ assertNotNull(addresses_g);
+ assertFalse(addresses_g.isAddedByUses());
+ assertFalse(addresses_u.equals(addresses_g));
+
+ // grouping defined by 'uses'
+ Set<GroupingDefinition> groupings_u = destination.getGroupings();
+ assertEquals(1, groupings_u.size());
+ GroupingDefinition grouping_u = groupings_u.iterator().next();
+ assertTrue(grouping_u.isAddedByUses());
+
+ // grouping defined in 'grouping' node
+ Set<GroupingDefinition> groupings_g = grouping.getGroupings();
+ assertEquals(1, groupings_g.size());
+ GroupingDefinition grouping_g = groupings_g.iterator().next();
+ assertFalse(grouping_g.isAddedByUses());
+ assertFalse(grouping_u.equals(grouping_g));
+
+ List<UnknownSchemaNode> nodes_u = destination.getUnknownSchemaNodes();
+ assertEquals(1, nodes_u.size());
+ UnknownSchemaNode node_u = nodes_u.get(0);
+ assertTrue(node_u.isAddedByUses());
+
+ List<UnknownSchemaNode> nodes_g = grouping.getUnknownSchemaNodes();
+ assertEquals(1, nodes_g.size());
+ UnknownSchemaNode node_g = nodes_g.get(0);
+ assertFalse(node_g.isAddedByUses());
+ assertFalse(node_u.equals(node_g));
+
+ UsesNode un = uses.iterator().next();
+ Set<AugmentationSchema> usesAugments = un.getAugmentations();
+ assertEquals(1, usesAugments.size());
+ AugmentationSchema augment = usesAugments.iterator().next();
+ assertEquals("inner augment", augment.getDescription());
+ Set<DataSchemaNode> children = augment.getChildNodes();
+ assertEquals(1, children.size());
+ DataSchemaNode leaf = children.iterator().next();
+ assertTrue(leaf instanceof LeafSchemaNode);
+ assertEquals("name", leaf.getQName().getLocalName());
+ }
+
}
TypeDefinition<?> testedType = TestUtils.findTypedef(typedefs, "service-type-ref");
IdentityrefType baseType = (IdentityrefType) testedType.getBaseType();
QName identity = baseType.getIdentity();
- assertEquals(URI.create("urn:simple.container.demo"), identity.getNamespace());
+ assertEquals(URI.create("urn:custom.types.demo"), identity.getNamespace());
assertEquals(TestUtils.createDate("2012-04-16"), identity.getRevision());
assertEquals("iit", identity.getPrefix());
assertEquals("service-type", identity.getLocalName());
+
+ LeafSchemaNode type = (LeafSchemaNode)tested.getDataChildByName("type");
+ assertNotNull(type);
+ TypeDefinition<?> leafType = type.getType();
+ assertEquals(testedType, leafType);
}
}
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.junit.Test;
fail("YangParseException should by thrown");
}
} catch (YangParseException e) {
- assertTrue(e.getMessage().contains(
- "Error in module 'test2' on line 24: Referenced type 'int-ext' not found."));
+ assertEquals(e.getMessage(), "Error in module 'test2' at line 24: Referenced type 'int-ext' not found.");
}
}
fail("YangParseException should by thrown");
}
} catch (YangParseException e) {
- assertTrue(e.getMessage()
- .contains("Error in module 'container' on line 10: Duplicate node found at line 6"));
+ String expected = "Error in module 'container' at line 10: Can not add 'container foo': node with same name already declared at line 6";
+ assertEquals(expected, e.getMessage());
}
}
fail("YangParseException should by thrown");
}
} catch (YangParseException e) {
- assertTrue(e.getMessage().contains(
- "Error in module 'container-list' on line 10: Duplicate node found at line 6"));
+ String expected = "Error in module 'container-list' at line 10: Can not add 'list foo': node with same name already declared at line 6";
+ assertEquals(expected, e.getMessage());
}
}
fail("YangParseException should by thrown");
}
} catch (YangParseException e) {
- assertTrue(e.getMessage().contains(
- "Error in module 'container-leaf' on line 10: Duplicate node found at line 6"));
+ String expected = "Error in module 'container-leaf' at line 10: Can not add 'leaf foo': node with same name already declared at line 6";
+ assertEquals(expected, e.getMessage());
}
}
fail("YangParseException should by thrown");
}
} catch (YangParseException e) {
- assertTrue(e.getMessage().contains("Error in module 'typedef' on line 10: Duplicate node found at line 6"));
+ String expected = "Error in module 'typedef' at line 10: typedef with same name 'int-ext' already declared at line 6";
+ assertEquals(expected, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDuplicityInAugmentTarget1() throws Exception {
+ try {
+ try (InputStream stream1 = new FileInputStream(getClass().getResource(
+ "/negative-scenario/duplicity/augment0.yang").getPath());
+ InputStream stream2 = new FileInputStream(getClass().getResource(
+ "/negative-scenario/duplicity/augment1.yang").getPath())) {
+ TestUtils.loadModules(Arrays.asList(stream1, stream2));
+ fail("YangParseException should by thrown");
+ }
+ } catch (YangParseException e) {
+ String expected = "Error in module 'augment1' at line 11: Can not add 'leaf id' to 'container bar' in module 'augment0': node with same name already declared at line 9";
+ assertEquals(expected, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDuplicityInAugmentTarget2() throws Exception {
+ try {
+ try (InputStream stream1 = new FileInputStream(getClass().getResource(
+ "/negative-scenario/duplicity/augment0.yang").getPath());
+ InputStream stream2 = new FileInputStream(getClass().getResource(
+ "/negative-scenario/duplicity/augment2.yang").getPath())) {
+ TestUtils.loadModules(Arrays.asList(stream1, stream2));
+ fail("YangParseException should by thrown");
+ }
+ } catch (YangParseException e) {
+ String expected = "Error in module 'augment2' at line 11: Can not add 'anyxml delta' to node 'choice-ext' in module 'augment0': case with same name already declared at line 18";
+ assertEquals(expected, e.getMessage());
}
}
}
@Test
- public void testOrderingNestedChildNodes() {
+ public void testOrderingNestedChildNodes1() {
+ Module test = TestUtils.findModule(modules, "nodes");
+
+ Set<DataSchemaNode> childNodes = test.getChildNodes();
+ String[] expectedOrder = new String[] { "address", "addresses", "custom-union-leaf", "data", "datas",
+ "decimal-leaf", "decimal-leaf2", "ext", "how", "int32-leaf", "length-leaf", "mycont", "peer", "port",
+ "string-leaf", "transfer", "union-leaf" };
+ String[] actualOrder = new String[childNodes.size()];
+
+ int i = 0;
+ for (DataSchemaNode child : childNodes) {
+ actualOrder[i] = child.getQName().getLocalName();
+ i++;
+ }
+ assertArrayEquals(expectedOrder, actualOrder);
+ }
+
+ @Test
+ public void testOrderingNestedChildNodes2() {
Module test = TestUtils.findModule(modules, "custom");
Set<GroupingDefinition> groupings = test.getGroupings();
assertEquals(1, groupings.size());
// test DataNodeContainer args
assertEquals(0, interfaces.getTypeDefinitions().size());
assertEquals(1, interfaces.getChildNodes().size());
- assertEquals(0, interfaces.getGroupings().size());
+ assertEquals(1, interfaces.getGroupings().size());
assertEquals(0, interfaces.getUses().size());
ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
@Test
public void testAnyXml() {
Module testModule = TestUtils.findModule(modules, "nodes");
- AnyXmlSchemaNode data = (AnyXmlSchemaNode) testModule.getDataChildByName("data");
+ AnyXmlSchemaNode data = (AnyXmlSchemaNode) testModule.getDataChildByName("datas");
assertNotNull("anyxml data not found", data);
// test SchemaNode args
QName qname = data.getQName();
- assertEquals("data", qname.getLocalName());
+ assertEquals("datas", qname.getLocalName());
assertEquals("n", qname.getPrefix());
assertEquals(nodesNS, qname.getNamespace());
assertEquals(nodesRev, qname.getRevision());
IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
QName idBaseQName = baseIdentity.getQName();
- assertEquals(URI.create("urn:simple.container.demo"), idBaseQName.getNamespace());
+ assertEquals(URI.create("urn:custom.types.demo"), idBaseQName.getNamespace());
assertEquals(simpleDateFormat.parse("2012-04-16"), idBaseQName.getRevision());
assertEquals("iit", idBaseQName.getPrefix());
assertEquals("service-type", idBaseQName.getLocalName());
UnknownSchemaNode un = unknownNodes.get(0);
QName unType = un.getNodeType();
- assertEquals(URI.create("urn:simple.container.demo"), unType.getNamespace());
+ assertEquals(URI.create("urn:custom.types.demo"), unType.getNamespace());
assertEquals(simpleDateFormat.parse("2012-04-16"), unType.getRevision());
assertEquals("custom", unType.getPrefix());
assertEquals("mountpoint", unType.getLocalName());
}
}
- anyxml data {
+ anyxml datas {
description
"Copy of the source typesstore subset that matched
the filter criteria (if any). An empty types container
}
}
+ uses c:target {
+ augment "/mycont/innercont" {
+ description "inner augment";
+ leaf name {
+ type string;
+ }
+ }
+ }
+
container peer {
container destination {
uses c:target {
yang-version 1;
namespace "urn:simple.types.test";
prefix "t";
-
+
organization "opendaylight";
contact "http://www.opendaylight.org/";
description "This is types-data test description";
length "6..10";
}
}
-
+
typedef string-ext3 {
type string-ext2 {
pattern "[b-u]*";
}
container interfaces {
- list ifEntry {
- key "ifIndex";
+ grouping ifEntry {
+ container augment-holder;
+ }
+ list ifEntry {
+ key "ifIndex";
- leaf ifIndex {
- type uint32;
- units minutes;
- }
+ leaf ifIndex {
+ type uint32;
+ units minutes;
+ }
- leaf ifMtu {
- type int32;
- }
+ leaf ifMtu {
+ type int32;
+ }
- min-elements 1;
- max-elements 11;
- }
+ min-elements 1;
+ max-elements 11;
+ }
}
}
--- /dev/null
+module augment0 {
+ yang-version 1;
+ namespace "urn:simple.augment0.demo";
+ prefix "a0";
+
+ container foo {
+ description "foo container";
+ container bar {
+ leaf id {
+ type int8;
+ }
+ typedef int-ext {
+ type int8 {
+ range "5..10";
+ }
+ }
+ choice choice-ext {
+ leaf delta {
+ type int8;
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+module augment1 {
+ yang-version 1;
+ namespace "urn:simple.augment1.demo";
+ prefix "a1";
+
+ import augment0 {
+ prefix "a0";
+ }
+
+ augment "/a0:foo/a0:bar" {
+ leaf id {
+ type string;
+ }
+ }
+
+}
--- /dev/null
+module augment2 {
+ yang-version 1;
+ namespace "urn:simple.augment2.demo";
+ prefix "a2";
+
+ import augment0 {
+ prefix "a0";
+ }
+
+ augment "/a0:foo/a0:bar/a0:choice-ext" {
+ anyxml delta;
+ }
+
+}
module custom-types-test {
- yang-version 1;
- namespace "urn:simple.container.demo";
+ yang-version 1;
+ namespace "urn:custom.types.demo";
prefix "iit";
-
+
organization "opendaylight";
contact "WILL-BE-DEFINED-LATER";
revision 2012-04-16 {
}
-
-
+
typedef access-operations-type {
type bits {
bit create {
}
description "NETCONF Access Operation.";
}
-
+
leaf inst-id-leaf1 {
type instance-identifier {
require-instance false;
}
}
-
+
leaf inst-id-leaf2 {
type instance-identifier;
}
+ leaf type {
+ type service-type-ref;
+ }
+
identity crypto-base {
description "crypto-base description";
}
base "crypto-base";
description "crypto-alg description";
}
-
+
leaf mybits {
type bits {
bit disable-nagle {
}
default "auto-sense-speed";
}
-
- typedef ip-version {
- type enumeration {
- enum unknown {
- description
- "An unknown or unspecified version of the Internet protocol.";
- }
- enum ipv4 {
- value "19";
- description
- "The IPv4 protocol as defined in RFC 791.";
- }
- enum ipv6 {
- value "7";
- description
- "The IPv6 protocol as defined in RFC 2460.";
- }
- enum default {
- description
- "default ip";
- }
- }
- }
-
- identity service-type {
- description
+
+ typedef ip-version {
+ type enumeration {
+ enum unknown {
+ description "An unknown or unspecified version of the Internet protocol.";
+ }
+ enum ipv4 {
+ value "19";
+ description "The IPv4 protocol as defined in RFC 791.";
+ }
+ enum ipv6 {
+ value "7";
+ description "The IPv6 protocol as defined in RFC 2460.";
+ }
+ enum default {
+ description "default ip";
+ }
+ }
+ }
+
+ identity service-type {
+ description
"Service identity base type. All service identities must be
derived from this type. A service type uniquely defines a single
atomic API contract, such as a Java interface, a set of C
of that interface should be attached to the derived identity MUST
include a java-class keyword, whose name argument points to that
interface.";
- }
+ }
- typedef service-type-ref {
- description
+ typedef service-type-ref {
+ description
"Internal type of references to service type identity.";
-
- type identityref {
- base service-type;
+ type identityref {
+ base service-type;
+ }
}
- }
}
-<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">\r
- <modelVersion>4.0.0</modelVersion>\r
- <parent>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>yang</artifactId>\r
- <version>0.5.4-SNAPSHOT</version>\r
- </parent>\r
- <artifactId>yang-model-util</artifactId>\r
- <dependencies>\r
- <dependency>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>yang-model-api</artifactId>\r
- </dependency>\r
- </dependencies>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+ <parent>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang</artifactId>\r
+ <version>0.5.4-SNAPSHOT</version>\r
+ </parent>\r
+\r
+ <modelVersion>4.0.0</modelVersion>\r
+ <artifactId>yang-model-util</artifactId>\r
+ <name>${project.artifactId}</name>\r
+ <description>${project.artifactId}</description>\r
+\r
+ <dependencies>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>yang-model-api</artifactId>\r
+ </dependency>\r
+ </dependencies>\r
+\r
</project>\r
/**
*
- * @param actualPath
- * @param namespace
- * @param revision
- * @param name
+ * @param path uint type schema path
+ * @param name qname
* @param description
- * @param MIN_VALUE
* @param maxRange
* @param units
*/
}
/**
- * @param name
+ *
+ * @param path uint type schema path
+ * @param name qname
* @param description
* @param rangeStatements
* @param units
/**
* Default constructor. <br>
* Instantiates Bits type as empty bits list.
+ *
+ * @param path
*/
public BitsType(final SchemaPath path) {
super();
/**
* Constructor with explicit definition of bits assigned to BitsType.
*
- * @param actualPath
- * @param namespace
- * @param revision
+ * @param path
* @param bits
- * The bits assigned for Bits Type
*/
public BitsType(final SchemaPath path, final List<Bit> bits) {
super();
final int prime = 31;
int result = 1;
result = prime * result + ((bits == null) ? 0 : bits.hashCode());
- result = prime * result
- + ((description == null) ? 0 : description.hashCode());
+ result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((path == null) ? 0 : path.hashCode());
- result = prime * result
- + ((reference == null) ? 0 : reference.hashCode());
+ result = prime * result + ((reference == null) ? 0 : reference.hashCode());
result = prime * result + ((units == null) ? 0 : units.hashCode());
return result;
}
org.apache.felix.dm
</Import-Package>
<Export-Package>
- org.opendaylight.controller.sample.simpleforwarding
+ org.opendaylight.controller.samples.simpleforwarding
</Export-Package>
<Bundle-Activator>
org.opendaylight.controller.samples.simpleforwarding.internal.Activator
import org.opendaylight.controller.sal.utils.IObjectReader;
import org.opendaylight.controller.sal.utils.ObjectReader;
import org.opendaylight.controller.sal.utils.ObjectWriter;
-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.switchmanager.IInventoryListener;
private String subnetFileName = null, spanFileName = null,
switchConfigFileName = null;
private final List<NodeConnector> spanNodeConnectors = new CopyOnWriteArrayList<NodeConnector>();
- private ConcurrentMap<InetAddress, Subnet> subnets; // set of Subnets keyed by the InetAddress
+ // set of Subnets keyed by the InetAddress
+ private ConcurrentMap<InetAddress, Subnet> subnets;
private ConcurrentMap<String, SubnetConfig> subnetsConfigList;
private ConcurrentMap<SpanConfig, SpanConfig> spanConfigList;
- private ConcurrentMap<String, SwitchConfig> nodeConfigList; // manually configured parameters for the node like name and tier
+ // manually configured parameters for the node such as name, tier, mode
+ private ConcurrentMap<String, SwitchConfig> nodeConfigList;
private ConcurrentMap<Long, String> configSaveEvent;
- private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in global container only
- private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in global container only
+ private ConcurrentMap<Node, Map<String, Property>> nodeProps;
+ private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps;
private ConcurrentMap<Node, Map<String, NodeConnector>> nodeConnectorNames;
private IInventoryService inventoryService;
private final Set<ISwitchManagerAware> switchManagerAware = Collections
modeChange = true;
}
- try {
- String nodeId = cfgObject.getNodeId();
- Node node = Node.fromString(nodeId);
- Map<String, Property> propMapCurr = nodeProps.get(node);
- Map<String, Property> propMap = new HashMap<String, Property>();
- if (propMapCurr != null) {
- for (String s : propMapCurr.keySet()) {
- propMap.put(s, propMapCurr.get(s).clone());
- }
- }
- Property desc = new Description(cfgObject.getNodeDescription());
- propMap.put(desc.getName(), desc);
- Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
- propMap.put(tier.getName(), tier);
+ String nodeId = cfgObject.getNodeId();
+ Node node = Node.fromString(nodeId);
+ Map<String, Property> propMapCurr = nodeProps.get(node);
+ if (propMapCurr == null) {
+ return;
+ }
+ Map<String, Property> propMap = new HashMap<String, Property>();
+ for (String s : propMapCurr.keySet()) {
+ propMap.put(s, propMapCurr.get(s).clone());
+ }
+ Property desc = new Description(cfgObject.getNodeDescription());
+ propMap.put(desc.getName(), desc);
+ Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
+ propMap.put(tier.getName(), tier);
- if (propMapCurr == null) {
- if (nodeProps.putIfAbsent(node, propMap) != null) {
- // TODO rollback using Transactionality
- return;
- }
- } else {
- if (!nodeProps.replace(node, propMapCurr, propMap)) {
- // TODO rollback using Transactionality
- return;
- }
- }
+ if (!nodeProps.replace(node, propMapCurr, propMap)) {
+ // TODO rollback using Transactionality
+ return;
+ }
- log.info("Set Node {}'s Mode to {}", nodeId, cfgObject.getMode());
+ log.info("Set Node {}'s Mode to {}", nodeId, cfgObject.getMode());
- if (modeChange) {
- notifyModeChange(node, cfgObject.isProactive());
- }
- } catch (Exception e) {
- log.debug("updateSwitchConfig: {}", e.getMessage());
+ if (modeChange) {
+ notifyModeChange(node, cfgObject.isProactive());
}
}
}
// copy node properties from plugin
- if (props != null) {
- for (Property prop : props) {
- propMap.put(prop.getName(), prop);
- }
+ for (Property prop : props) {
+ propMap.put(prop.getName(), prop);
}
if (propMapCurr == null) {
@Override
public void updateNodeConnector(NodeConnector nodeConnector,
UpdateType type, Set<Property> props) {
- Node node = nodeConnector.getNode();
Map<String, Property> propMap = new HashMap<String, Property>();
log.debug("updateNodeConnector: {} type {} props {} for container {}",
}
} else {
addNodeConnectorProp(nodeConnector, null);
- addNodeProps(node, null);
}
addSpanPort(nodeConnector);
break;
case REMOVED:
removeNodeConnectorAllProps(nodeConnector);
- removeNodeProps(node);
// clean up span config
removeSpanPort(nodeConnector);
*/
@Override
public Map<String, Property> getNodeProps(Node node) {
- if (isDefaultContainer) {
- Map<String, Property> rv = null;
- if (this.nodeProps != null) {
- rv = this.nodeProps.get(node);
- if (rv != null) {
- /* make a copy of it */
- rv = new HashMap<String, Property>(rv);
- }
+ Map<String, Property> rv = new HashMap<String, Property>();
+ if (this.nodeProps != null) {
+ rv = this.nodeProps.get(node);
+ if (rv != null) {
+ /* make a copy of it */
+ rv = new HashMap<String, Property>(rv);
}
- return rv;
- } else {
- // get it from default container
- ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper
- .getInstance(ISwitchManager.class,
- GlobalConstants.DEFAULT.toString(), this);
- return defaultSwitchManager.getNodeProps(node);
}
+ return rv;
}
@Override
return;
}
if (!propMapCurr.get(prop.getName()).equals(nodeProps.get(node).get(prop.getName()))) {
- log.warn("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID());
+ log.debug("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID());
return;
}
}
}
@Override
- public Map<String, Property> getNodeConnectorProps(
- NodeConnector nodeConnector) {
- if (isDefaultContainer) {
- Map<String, Property> rv = null;
- if (this.nodeConnectorProps != null) {
- rv = this.nodeConnectorProps.get(nodeConnector);
- if (rv != null) {
- rv = new HashMap<String, Property>(rv);
- }
+ public Map<String, Property> getNodeConnectorProps(NodeConnector nodeConnector) {
+ Map<String, Property> rv = new HashMap<String, Property>();
+ if (this.nodeConnectorProps != null) {
+ rv = this.nodeConnectorProps.get(nodeConnector);
+ if (rv != null) {
+ rv = new HashMap<String, Property>(rv);
}
- return rv;
- } else {
- // get it from default container
- ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper
- .getInstance(ISwitchManager.class,
- GlobalConstants.DEFAULT.toString(), this);
- return defaultSwitchManager.getNodeConnectorProps(nodeConnector);
}
+ return rv;
}
@Override
package org.opendaylight.controller.topologymanager;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.Node.NodeIDType;
-import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.utils.GUIField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
if (!isValidNodeConnector(srcNodeConnector) ||
!isValidNodeConnector(dstNodeConnector)) {
- logger.warn("Invalid NodeConnector");
+ logger.debug("Invalid NodeConnector in user link: {}", this);
return false;
}
package org.opendaylight.controller.topologymanager.internal;
-import org.apache.felix.dm.Component;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
public void configureInstance(Component c, Object imp, String containerName) {
if (imp.equals(TopologyManagerImpl.class)) {
// export the service needed to listen to topology updates
+ Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
+ Set<String> propSet = new HashSet<String>();
+ propSet.add("topologymanager.configSaveEvent");
+ props.put("cachenames", propSet);
+
c.setInterface(new String[] { IListenTopoUpdates.class.getName(),
ITopologyManager.class.getName(),
- IConfigurationContainerAware.class.getName() }, null);
+ IConfigurationContainerAware.class.getName() }, props);
c.add(createContainerServiceDependency(containerName).setService(
ITopologyService.class).setCallbacks("setTopoService",
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Date;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.felix.dm.Component;
public class TopologyManagerImpl implements ITopologyManager,
IConfigurationContainerAware, IListenTopoUpdates, IObjectReader,
CommandProvider {
- private static final Logger log = LoggerFactory
- .getLogger(TopologyManagerImpl.class);
- private ITopologyService topoService = null;
- private IClusterContainerServices clusterContainerService = null;
+ private static final Logger log = LoggerFactory.getLogger(TopologyManagerImpl.class);
+ private static final String SAVE = "Save";
+ private ITopologyService topoService;
+ private IClusterContainerServices clusterContainerService;
// DB of all the Edges with properties which constitute our topology
- private ConcurrentMap<Edge, Set<Property>> edgesDB = null;
+ private ConcurrentMap<Edge, Set<Property>> edgesDB;
// DB of all NodeConnector which are part of ISL Edges, meaning they
// are connected to another NodeConnector on the other side of an ISL link.
// NodeConnector of a Production Edge is not part of this DB.
- private ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorsDB = null;
+ private ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorsDB;
// DB of all the NodeConnectors with an Host attached to it
- private ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>> hostsDB = null;
+ private ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>> hostsDB;
// Topology Manager Aware listeners
- private Set<ITopologyManagerAware> topologyManagerAware = Collections
- .synchronizedSet(new HashSet<ITopologyManagerAware>());
+ private Set<ITopologyManagerAware> topologyManagerAware =
+ new CopyOnWriteArraySet<ITopologyManagerAware>();;
private static String ROOT = GlobalConstants.STARTUPHOME.toString();
- private String userLinksFileName = null;
- private ConcurrentMap<String, TopologyUserLinkConfig> userLinks;
+ private String userLinksFileName;
+ private ConcurrentMap<String, TopologyUserLinkConfig> userLinksDB;
+ private ConcurrentMap<Long, String> configSaveEvent;
+
void nonClusterObjectCreate() {
edgesDB = new ConcurrentHashMap<Edge, Set<Property>>();
hostsDB = new ConcurrentHashMap<NodeConnector, ImmutablePair<Host, Set<Property>>>();
- userLinks = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
nodeConnectorsDB = new ConcurrentHashMap<NodeConnector, Set<Property>>();
+ userLinksDB = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
+ configSaveEvent = new ConcurrentHashMap<Long, String>();
}
void setTopologyManagerAware(ITopologyManagerAware s) {
*
*/
void init(Component c) {
+
+ allocateCaches();
+ retrieveCaches();
+
String containerName = null;
- Dictionary props = c.getServiceProperties();
+ Dictionary<?, ?> props = c.getServiceProperties();
if (props != null) {
containerName = (String) props.get("containerName");
} else {
containerName = "UNKNOWN";
}
- if (this.clusterContainerService == null) {
- log.error("Cluster Services is null, not expected!");
- return;
- }
+ userLinksFileName = ROOT + "userTopology_" + containerName + ".conf";
+ registerWithOSGIConsole();
+ loadConfiguration();
+ }
- if (this.topoService == null) {
- log.error("Topology Services is null, not expected!");
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ private void allocateCaches(){
+ if (this.clusterContainerService == null) {
+ nonClusterObjectCreate();
+ log.error("Cluster Services unavailable, allocated non-cluster caches!");
return;
}
try {
- this.edgesDB = (ConcurrentMap<Edge, Set<Property>>) this.clusterContainerService
- .createCache("topologymanager.edgesDB", EnumSet
- .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ this.edgesDB = (ConcurrentMap<Edge, Set<Property>>) this.clusterContainerService.createCache(
+ "topologymanager.edgesDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
} catch (CacheExistException cee) {
- log.error("topologymanager.edgesDB Cache already exists - "
- + "destroy and recreate if needed");
+ log.debug("topologymanager.edgesDB Cache already exists - destroy and recreate if needed");
} catch (CacheConfigException cce) {
- log.error("topologymanager.edgesDB Cache configuration invalid - "
- + "check cache mode");
+ log.error("topologymanager.edgesDB Cache configuration invalid - check cache mode");
}
try {
this.hostsDB = (ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>>) this.clusterContainerService
- .createCache("topologymanager.hostsDB", EnumSet
- .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ .createCache("topologymanager.hostsDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
} catch (CacheExistException cee) {
- log.error("topologymanager.hostsDB Cache already exists - "
- + "destroy and recreate if needed");
+ log.debug("topologymanager.hostsDB Cache already exists - destroy and recreate if needed");
} catch (CacheConfigException cce) {
- log.error("topologymanager.hostsDB Cache configuration invalid - "
- + "check cache mode");
+ log.error("topologymanager.hostsDB Cache configuration invalid - check cache mode");
}
try {
this.nodeConnectorsDB = (ConcurrentMap<NodeConnector, Set<Property>>) this.clusterContainerService
- .createCache("topologymanager.nodeConnectorDB", EnumSet
- .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ .createCache("topologymanager.nodeConnectorDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
} catch (CacheExistException cee) {
- log.error("topologymanager.nodeConnectorDB Cache already exists"
- + " - destroy and recreate if needed");
+ log.debug("topologymanager.nodeConnectorDB Cache already exists - destroy and recreate if needed");
} catch (CacheConfigException cce) {
- log.error("topologymanager.nodeConnectorDB Cache configuration "
- + "invalid - check cache mode");
+ log.error("topologymanager.nodeConnectorDB Cache configuration invalid - check cache mode");
}
- userLinks = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
+ try {
+ this.userLinksDB = (ConcurrentMap<String, TopologyUserLinkConfig>) this.clusterContainerService
+ .createCache("topologymanager.userLinksDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ } catch (CacheExistException cee) {
+ log.debug("topologymanager.userLinksDB Cache already exists - destroy and recreate if needed");
+ } catch (CacheConfigException cce) {
+ log.error("topologymanager.userLinksDB Cache configuration invalid - check cache mode");
+ }
+
+ try {
+ this.configSaveEvent = (ConcurrentMap<Long, String>) this.clusterContainerService
+ .createCache("topologymanager.configSaveEvent", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ } catch (CacheExistException cee) {
+ log.debug("topologymanager.configSaveEvent Cache already exists - destroy and recreate if needed");
+ } catch (CacheConfigException cce) {
+ log.error("topologymanager.configSaveEvent Cache configuration invalid - check cache mode");
+ }
+
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ private void retrieveCaches() {
+ if (this.clusterContainerService == null) {
+ log.error("Cluster Services is null, can't retrieve caches.");
+ return;
+ }
+
+ this.edgesDB = (ConcurrentMap<Edge, Set<Property>>) this.clusterContainerService
+ .getCache("topologymanager.edgesDB");
+ if (edgesDB == null) {
+ log.error("Failed to get cache for topologymanager.edgesDB");
+ }
+
+ this.hostsDB = (ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>>) this.clusterContainerService
+ .getCache("topologymanager.hostsDB");
+ if (hostsDB == null) {
+ log.error("Failed to get cache for topologymanager.hostsDB");
+ }
+
+ this.nodeConnectorsDB = (ConcurrentMap<NodeConnector, Set<Property>>) this.clusterContainerService
+ .getCache("topologymanager.nodeConnectorDB");
+ if (nodeConnectorsDB == null) {
+ log.error("Failed to get cache for topologymanager.nodeConnectorDB");
+ }
+
+ this.userLinksDB = (ConcurrentMap<String, TopologyUserLinkConfig>) this.clusterContainerService
+ .getCache("topologymanager.userLinksDB");
+ if (userLinksDB == null) {
+ log.error("Failed to get cache for topologymanager.userLinksDB");
+ }
+
+ this.configSaveEvent = (ConcurrentMap<Long, String>) this.clusterContainerService
+ .getCache("topologymanager.configSaveEvent");
+ if (configSaveEvent == null) {
+ log.error("Failed to get cache for topologymanager.configSaveEvent");
+ }
- userLinksFileName = ROOT + "userTopology_" + containerName + ".conf";
- registerWithOSGIConsole();
- loadConfiguration();
}
/**
*
*/
void destroy() {
- if (this.clusterContainerService == null) {
- log.error("Cluster Services is null, not expected!");
- this.edgesDB = null;
- this.hostsDB = null;
- this.nodeConnectorsDB = null;
- return;
- }
- this.clusterContainerService.destroyCache("topologymanager.edgesDB");
- this.edgesDB = null;
- this.clusterContainerService.destroyCache("topologymanager.hostsDB");
- this.hostsDB = null;
- this.clusterContainerService
- .destroyCache("topologymanager.nodeConnectorDB");
- this.nodeConnectorsDB = null;
- log.debug("Topology Manager DB Deallocated");
}
@SuppressWarnings("unchecked")
private void loadConfiguration() {
ObjectReader objReader = new ObjectReader();
- ConcurrentMap<String, TopologyUserLinkConfig> confList = (ConcurrentMap<String, TopologyUserLinkConfig>) objReader
- .read(this, userLinksFileName);
-
- if (confList == null) {
- return;
- }
+ ConcurrentMap<String, TopologyUserLinkConfig> confList =
+ (ConcurrentMap<String, TopologyUserLinkConfig>) objReader.read(this, userLinksFileName);
- for (TopologyUserLinkConfig conf : confList.values()) {
- addUserLink(conf);
+ if (confList != null) {
+ for (TopologyUserLinkConfig conf : confList.values()) {
+ addUserLink(conf);
+ }
}
}
@Override
public Status saveConfig() {
- // Publish the save config event to the cluster nodes
- /**
- * Get the CLUSTERING SERVICES WORKING BEFORE TRYING THIS
- *
- * configSaveEvent.put(new Date().getTime(), SAVE);
- */
+ // Publish the save config event to the cluster
+ configSaveEvent.put(new Date().getTime(), SAVE );
return saveConfigInternal();
}
public Status saveConfigInternal() {
- Status retS;
ObjectWriter objWriter = new ObjectWriter();
- retS = objWriter
- .write(new ConcurrentHashMap<String, TopologyUserLinkConfig>(
- userLinks), userLinksFileName);
+ Status saveStatus = objWriter.write(
+ new ConcurrentHashMap<String, TopologyUserLinkConfig>(userLinksDB), userLinksFileName);
- if (retS.isSuccess()) {
- return retS;
- } else {
- return new Status(StatusCode.INTERNALERROR, "Save failed");
+ if (! saveStatus.isSuccess()) {
+ return new Status(StatusCode.INTERNALERROR, "Topology save failed: " + saveStatus.getDescription());
}
+ return saveStatus;
}
@Override
return null;
}
- HashMap<Node, Set<Edge>> res = new HashMap<Node, Set<Edge>>();
- for (Edge key : this.edgesDB.keySet()) {
+ Map<Node, Set<Edge>> res = new HashMap<Node, Set<Edge>>();
+ for (Edge edge : this.edgesDB.keySet()) {
// Lets analyze the tail
- Node node = key.getTailNodeConnector().getNode();
+ Node node = edge.getTailNodeConnector().getNode();
Set<Edge> nodeEdges = res.get(node);
if (nodeEdges == null) {
nodeEdges = new HashSet<Edge>();
+ res.put(node, nodeEdges);
}
- nodeEdges.add(key);
- // We need to re-add to the MAP even if the element was
- // already there so in case of clustered services the map
- // gets updated in the cluster
- res.put(node, nodeEdges);
+ nodeEdges.add(edge);
// Lets analyze the head
- node = key.getHeadNodeConnector().getNode();
+ node = edge.getHeadNodeConnector().getNode();
nodeEdges = res.get(node);
if (nodeEdges == null) {
nodeEdges = new HashSet<Edge>();
+ res.put(node, nodeEdges);
}
- nodeEdges.add(key);
- // We need to re-add to the MAP even if the element was
- // already there so in case of clustered services the map
- // gets updated in the cluster
- res.put(node, nodeEdges);
+ nodeEdges.add(edge);
}
return res;
* @return true if it is a production link
*/
public boolean isProductionLink(Edge e) {
- return (e.getHeadNodeConnector().getType()
- .equals(NodeConnector.NodeConnectorIDType.PRODUCTION) || e
- .getTailNodeConnector().getType()
- .equals(NodeConnector.NodeConnectorIDType.PRODUCTION));
+ return (e.getHeadNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)
+ || e.getTailNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION));
}
/**
return null;
}
- HashMap<Edge, Set<Property>> res = new HashMap<Edge, Set<Property>>();
- for (Edge key : this.edgesDB.keySet()) {
+ Map<Edge, Set<Property>> edgeMap = new HashMap<Edge, Set<Property>>();
+ Set<Property> props;
+ for (Map.Entry<Edge, Set<Property>> edgeEntry : edgesDB.entrySet()) {
// Sets of props are copied because the composition of
// those properties could change with time
- HashSet<Property> prop = new HashSet<Property>(
- this.edgesDB.get(key));
+ props = new HashSet<Property>(edgeEntry.getValue());
// We can simply reuse the key because the object is
// immutable so doesn't really matter that we are
// referencing the only owned by a different table, the
// meaning is the same because doesn't change with time.
- res.put(key, prop);
+ edgeMap.put(edgeEntry.getKey(), props);
}
- return res;
- }
-
- // TODO remove with spring-dm removal
- /**
- * @param set
- * the topologyAware to set
- */
- public void setTopologyAware(Set<Object> set) {
- for (Object s : set) {
- setTopologyManagerAware((ITopologyManagerAware) s);
- }
+ return edgeMap;
}
@Override
return null;
}
- return (this.hostsDB.keySet());
+ return (new HashSet<NodeConnector>(this.hostsDB.keySet()));
}
@Override
return null;
}
HashMap<Node, Set<NodeConnector>> res = new HashMap<Node, Set<NodeConnector>>();
-
- for (NodeConnector p : this.hostsDB.keySet()) {
- Node n = p.getNode();
- Set<NodeConnector> pSet = res.get(n);
- if (pSet == null) {
+ Node node;
+ Set<NodeConnector> portSet;
+ for (NodeConnector nc : this.hostsDB.keySet()) {
+ node = nc.getNode();
+ portSet = res.get(node);
+ if (portSet == null) {
// Create the HashSet if null
- pSet = new HashSet<NodeConnector>();
- res.put(n, pSet);
+ portSet = new HashSet<NodeConnector>();
+ res.put(node, portSet);
}
// Keep updating the HashSet, given this is not a
// clustered map we can just update the set without
// worrying to update the hashmap.
- pSet.add(p);
+ portSet.add(nc);
}
return (res);
}
@Override
- public Host getHostAttachedToNodeConnector(NodeConnector p) {
- if (this.hostsDB == null) {
+ public Host getHostAttachedToNodeConnector(NodeConnector port) {
+ ImmutablePair<Host, Set<Property>> host;
+ if (this.hostsDB == null || (host = this.hostsDB.get(port)) == null) {
return null;
}
- if (this.hostsDB.get(p) == null)
- return null;
-
- return (this.hostsDB.get(p).getLeft());
+ return host.getLeft();
}
@Override
- public void updateHostLink(NodeConnector p, Host h, UpdateType t,
- Set<Property> props) {
- if (this.hostsDB == null) {
- return;
+ public void updateHostLink(NodeConnector port, Host h, UpdateType t, Set<Property> props) {
+
+ // Clone the property set in case non null else just
+ // create an empty one. Caches allocated via infinispan
+ // don't allow null values
+ if (props == null) {
+ props = new HashSet<Property>();
+ } else {
+ props = new HashSet<Property>(props);
}
+ ImmutablePair<Host, Set<Property>> thisHost = new ImmutablePair<Host, Set<Property>>(h, props);
switch (t) {
case ADDED:
case CHANGED:
- // Clone the property set in case non null else just
- // create an empty one. Caches allocated via infinispan
- // don't allow null values
- if (props == null) {
- props = new HashSet<Property>();
- } else {
- props = new HashSet<Property>(props);
- }
-
- this.hostsDB.put(p, new ImmutablePair(h, props));
+ this.hostsDB.put(port, thisHost);
break;
case REMOVED:
- this.hostsDB.remove(p);
+ //remove only if hasn't been concurrently modified
+ this.hostsDB.remove(port, thisHost);
break;
}
}
- private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type,
- Set<Property> props) {
+ private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type, Set<Property> props) {
switch (type) {
case ADDED:
// Make sure the props are non-null
if (props == null) {
- props = (Set<Property>) new HashSet();
+ props = new HashSet<Property>();
} else {
- // Copy the set so noone is going to change the content
- props = (Set<Property>) new HashSet(props);
+ props = new HashSet<Property>(props);
+ }
+
+ //in case of node switch-over to a different cluster controller,
+ //let's retain edge props
+ Set<Property> currentProps = this.edgesDB.get(e);
+ if (currentProps != null){
+ props.addAll(currentProps);
}
// Now make sure there is the creation timestamp for the
- // edge, if not there timestamp with the first update
+ // edge, if not there, stamp with the first update
boolean found_create = false;
for (Property prop : props) {
if (prop instanceof TimeStamp) {
TimeStamp t = (TimeStamp) prop;
if (t.getTimeStampName().equals("creation")) {
found_create = true;
+ break;
}
}
}
if (!found_create) {
- TimeStamp t = new TimeStamp(System.currentTimeMillis(),
- "creation");
+ TimeStamp t = new TimeStamp(System.currentTimeMillis(), "creation");
props.add(t);
}
// for now.
// The DB only contains ISL ports
if (isISLink(e)) {
- this.nodeConnectorsDB.put(e.getHeadNodeConnector(),
- new HashSet<Property>());
- this.nodeConnectorsDB.put(e.getTailNodeConnector(),
- new HashSet<Property>());
+ this.nodeConnectorsDB.put(e.getHeadNodeConnector(), new HashSet<Property>(1));
+ this.nodeConnectorsDB.put(e.getTailNodeConnector(), new HashSet<Property>(1));
}
log.trace("Edge {} {}", e.toString(), type.name());
break;
log.trace("Edge {} {}", e.toString(), type.name());
break;
case CHANGED:
- Set<Property> old_props = this.edgesDB.get(e);
+ Set<Property> oldProps = this.edgesDB.get(e);
// When property changes lets make sure we can change it
// all except the creation time stamp because that should
// be changed only when the edge is destroyed and created
// again
- TimeStamp tc = null;
- for (Property prop : old_props) {
+ TimeStamp timeStamp = null;
+ for (Property prop : oldProps) {
if (prop instanceof TimeStamp) {
- TimeStamp t = (TimeStamp) prop;
- if (t.getTimeStampName().equals("creation")) {
- tc = t;
+ TimeStamp tsProp = (TimeStamp) prop;
+ if (tsProp.getTimeStampName().equals("creation")) {
+ timeStamp = tsProp;
+ break;
}
}
}
// Now lets make sure new properties are non-null
- // Make sure the props are non-null
if (props == null) {
- props = (Set<Property>) new HashSet();
+ props = new HashSet<Property>();
} else {
// Copy the set so noone is going to change the content
- props = (Set<Property>) new HashSet(props);
+ props = new HashSet<Property>(props);
}
// Now lets remove the creation property if exist in the
TimeStamp t = (TimeStamp) prop;
if (t.getTimeStampName().equals("creation")) {
i.remove();
+ break;
}
}
}
// Now lets add the creation timestamp in it
- if (tc != null) {
- props.add(tc);
+ if (timeStamp != null) {
+ props.add(timeStamp);
}
// Finally update
try {
s.edgeUpdate(teuList);
} catch (Exception exc) {
- log.error("Exception on callback", exc);
+ log.error("Exception on edge update:", exc);
}
}
private Edge getLinkTuple(TopologyUserLinkConfig link) {
- Edge linkTuple = null;
NodeConnector srcNodeConnector = NodeConnector.fromString(link.getSrcNodeConnector());
NodeConnector dstNodeConnector = NodeConnector.fromString(link.getDstNodeConnector());
- if (srcNodeConnector == null || dstNodeConnector == null) return null;
try {
- linkTuple = new Edge(srcNodeConnector, dstNodeConnector);
+ return new Edge(srcNodeConnector, dstNodeConnector);
} catch (Exception e) {
+ return null;
}
- return linkTuple;
}
@Override
public ConcurrentMap<String, TopologyUserLinkConfig> getUserLinks() {
- return userLinks;
+ return new ConcurrentHashMap<String, TopologyUserLinkConfig>(userLinksDB);
}
@Override
- public Status addUserLink(TopologyUserLinkConfig link) {
- if (!link.isValid()) {
+ public Status addUserLink(TopologyUserLinkConfig userLink) {
+ if (!userLink.isValid()) {
return new Status(StatusCode.BADREQUEST,
- "Configuration Invalid. Please check the parameters");
+ "User link configuration invalid.");
}
- if (userLinks.get(link.getName()) != null) {
- return new Status(StatusCode.CONFLICT, "Link with name : "
- + link.getName()
- + " already exists. Please use another name");
+ userLink.setStatus(TopologyUserLinkConfig.STATUS.LINKDOWN);
+
+ //Check if this link already configured
+ //NOTE: infinispan cache doesn't support Map.containsValue()
+ // (which is linear time in most ConcurrentMap impl anyway)
+ for (TopologyUserLinkConfig existingLink : userLinksDB.values()) {
+ if (existingLink.equals(userLink)) {
+ return new Status(StatusCode.CONFLICT, "Link configuration exists");
+ }
}
- if (userLinks.containsValue(link)) {
- return new Status(StatusCode.CONFLICT, "Link configuration exists");
+ //attempt put, if mapping for this key already existed return conflict
+ if (userLinksDB.putIfAbsent(userLink.getName(), userLink) != null) {
+ return new Status(StatusCode.CONFLICT, "Link with name : " + userLink.getName()
+ + " already exists. Please use another name");
}
- link.setStatus(TopologyUserLinkConfig.STATUS.LINKDOWN);
- userLinks.put(link.getName(), link);
-
- Edge linkTuple = getLinkTuple(link);
+ Edge linkTuple = getLinkTuple(userLink);
if (linkTuple != null) {
if (!isProductionLink(linkTuple)) {
edgeUpdate(linkTuple, UpdateType.ADDED, new HashSet<Property>());
}
- linkTuple = getReverseLinkTuple(link);
+ linkTuple = getReverseLinkTuple(userLink);
if (linkTuple != null) {
- link.setStatus(TopologyUserLinkConfig.STATUS.SUCCESS);
+ userLink.setStatus(TopologyUserLinkConfig.STATUS.SUCCESS);
if (!isProductionLink(linkTuple)) {
edgeUpdate(linkTuple, UpdateType.ADDED, new HashSet<Property>());
}
}
}
- return new Status(StatusCode.SUCCESS, null);
+ return new Status(StatusCode.SUCCESS);
}
@Override
public Status deleteUserLink(String linkName) {
if (linkName == null) {
- return new Status(StatusCode.BADREQUEST,
- "A valid linkName is required to Delete a link");
+ return new Status(StatusCode.BADREQUEST, "User link name cannot be null.");
}
- TopologyUserLinkConfig link = userLinks.get(linkName);
-
- Edge linkTuple = getLinkTuple(link);
- userLinks.remove(linkName);
- if (linkTuple != null) {
- if (!isProductionLink(linkTuple)) {
+ TopologyUserLinkConfig link = userLinksDB.remove(linkName);
+ Edge linkTuple;
+ if (link != null && (linkTuple = getLinkTuple(link)) != null) {
+ if (! isProductionLink(linkTuple)) {
edgeUpdate(linkTuple, UpdateType.REMOVED, null);
}
linkTuple = getReverseLinkTuple(link);
- if ((linkTuple != null) && !isProductionLink(linkTuple)) {
+ if (! isProductionLink(linkTuple)) {
edgeUpdate(linkTuple, UpdateType.REMOVED, null);
}
}
- return new Status(StatusCode.SUCCESS, null);
+ return new Status(StatusCode.SUCCESS);
}
private void registerWithOSGIConsole() {
}
public void _printUserLink(CommandInterpreter ci) {
- for (String name : this.userLinks.keySet()) {
- TopologyUserLinkConfig linkConfig = userLinks.get(name);
+ for (String name : this.userLinksDB.keySet()) {
+ TopologyUserLinkConfig linkConfig = userLinksDB.get(name);
ci.println("Name : " + name);
ci.println(linkConfig);
ci.println("Edge " + getLinkTuple(linkConfig));
@Override
public Object readObject(ObjectInputStream ois)
throws FileNotFoundException, IOException, ClassNotFoundException {
- // TODO Auto-generated method stub
return ois.readObject();
}