<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-api</artifactId>
<version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>flow-management-compatibility</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-service</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.services</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
</dependencies>
</project>
private ConcurrentMap<Node, List<Group>> nodeGroups;
private ConcurrentMap<GroupKey, Group> inactiveGroups;
- private IClusterContainerServices clusterGroupContainerService = null;
- private ISwitchManager switchGroupManager;
+ private IClusterContainerServices clusterGroupContainerService = null;
private IContainer container;
public GroupConsumerImpl() {
- InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class).toInstance();
+ InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class).node(Group.class).toInstance();
groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
- clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
- switchGroupManager = FRMConsumerImpl.getSwitchManager();
+ clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
container = FRMConsumerImpl.getContainer();
if (!(cacheStartup())) {
* @param dataObject
*/
private Status updateGroup(InstanceIdentifier<?> path, Group groupUpdateDataObject) {
- GroupKey groupKey = groupUpdateDataObject.getKey();
+ GroupKey groupKey = groupUpdateDataObject.getKey();
Status groupOperationStatus = validateGroup(groupUpdateDataObject, FRMUtil.operation.UPDATE);
if (!groupOperationStatus.isSuccess()) {
logger.error("Group data object validation failed %s" + groupAddDataObject.getGroupName());
return groupOperationStatus;
}
- validateGroup(groupAddDataObject, FRMUtil.operation.ADD);
+
originalSwGroupView.put(groupKey, groupAddDataObject);
if (groupAddDataObject.isInstall()) {
@Override
public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
// We should verify transaction
- System.out.println("Coming in FlowDatacommitHandler");
+ System.out.println("Coming in GroupDatacommitHandler");
internalTransaction transaction = new internalTransaction(modification);
transaction.prepareUpdate();
return transaction;
--- /dev/null
+package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.IContainer;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.Meters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.BandType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemark;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MeterConsumerImpl {
+ protected static final Logger logger = LoggerFactory.getLogger(MeterConsumerImpl.class);
+ private MeterEventListener meterEventListener = new MeterEventListener();
+ private Registration<NotificationListener> meterListener;
+ private SalMeterService meterService;
+ private MeterDataCommitHandler commitHandler;
+
+ private ConcurrentMap<MeterKey, Meter> originalSwMeterView;
+ private ConcurrentMap<MeterKey, Meter> installedSwMeterView;
+
+ private ConcurrentMap<Node, List<Meter>> nodeMeters;
+ private ConcurrentMap<MeterKey, Meter> inactiveMeters;
+
+ private IClusterContainerServices clusterMeterContainerService = null;
+ private IContainer container;
+
+ public MeterConsumerImpl() {
+ InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Meters.class).node(Meter.class).toInstance();
+ meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);
+ clusterMeterContainerService = FRMConsumerImpl.getClusterContainerService();
+
+ container = FRMConsumerImpl.getContainer();
+
+ if (!(cacheStartup())) {
+ logger.error("Unable to allocate/retrieve meter cache");
+ System.out.println("Unable to allocate/retrieve meter cache");
+ }
+
+ if (null == meterService) {
+ logger.error("Consumer SAL Meter Service is down or NULL. FRM may not function as intended");
+ System.out.println("Consumer SAL Meter Service is down or NULL.");
+ return;
+ }
+
+ // For switch/plugin events
+ meterListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(meterEventListener);
+
+ if (null == meterListener) {
+ logger.error("Listener to listen on meter data modifcation events");
+ System.out.println("Listener to listen on meter data modifcation events.");
+ return;
+ }
+
+ commitHandler = new MeterDataCommitHandler();
+ FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
+ }
+
+
+
+ private boolean allocateMeterCaches() {
+ if (this.clusterMeterContainerService == null) {
+ logger.warn("Meter: Un-initialized clusterMeterContainerService, can't create cache");
+ return false;
+ }
+
+ try {
+ clusterMeterContainerService.createCache("frm.originalSwMeterView",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ clusterMeterContainerService.createCache("frm.installedSwMeterView",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ clusterMeterContainerService.createCache("frm.inactiveMeters",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ clusterMeterContainerService.createCache("frm.nodeMeters",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+//TODO for cluster mode
+ /* clusterMeterContainerService.createCache(WORK_STATUS_CACHE,
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));
+
+ clusterMeterContainerService.createCache(WORK_ORDER_CACHE,
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));*/
+
+ } catch (CacheConfigException cce) {
+ logger.error("Meter CacheConfigException");
+ return false;
+
+ } catch (CacheExistException cce) {
+ logger.error(" Meter CacheExistException");
+ }
+
+ return true;
+ }
+
+ private void nonClusterMeterObjectCreate() {
+ originalSwMeterView = new ConcurrentHashMap<MeterKey, Meter>();
+ installedSwMeterView = new ConcurrentHashMap<MeterKey, Meter>();
+ nodeMeters = new ConcurrentHashMap<Node, List<Meter>>();
+ inactiveMeters = new ConcurrentHashMap<MeterKey, Meter>();
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private boolean retrieveMeterCaches() {
+ ConcurrentMap<?, ?> map;
+
+ if (this.clusterMeterContainerService == null) {
+ logger.warn("Meter: un-initialized clusterMeterContainerService, can't retrieve cache");
+ nonClusterMeterObjectCreate();
+ return false;
+ }
+
+ map = clusterMeterContainerService.getCache("frm.originalSwMeterView");
+ if (map != null) {
+ originalSwMeterView = (ConcurrentMap<MeterKey, Meter>) map;
+ } else {
+ logger.error("Retrieval of cache(originalSwMeterView) failed");
+ return false;
+ }
+
+ map = clusterMeterContainerService.getCache("frm.installedSwMeterView");
+ if (map != null) {
+ installedSwMeterView = (ConcurrentMap<MeterKey, Meter>) map;
+ } else {
+ logger.error("Retrieval of cache(installedSwMeterView) failed");
+ return false;
+ }
+
+ map = clusterMeterContainerService.getCache("frm.inactiveMeters");
+ if (map != null) {
+ inactiveMeters = (ConcurrentMap<MeterKey, Meter>) map;
+ } else {
+ logger.error("Retrieval of cache(inactiveMeters) failed");
+ return false;
+ }
+
+ map = clusterMeterContainerService.getCache("frm.nodeMeters");
+ if (map != null) {
+ nodeMeters = (ConcurrentMap<Node, List<Meter>>) map;
+ } else {
+ logger.error("Retrieval of cache(nodeMeter) failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean cacheStartup() {
+ if (allocateMeterCaches()) {
+ if (retrieveMeterCaches()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds Meter to the southbound plugin and our internal database
+ *
+ * @param path
+ * @param dataObject
+ */
+ private Status addMeter(InstanceIdentifier<?> path, Meter meterAddDataObject) {
+ MeterKey meterKey = meterAddDataObject.getKey();
+
+ if (null != meterKey &&
+ validateMeter(meterAddDataObject, FRMUtil.operation.ADD).isSuccess()) {
+ if (meterAddDataObject.isInstall()) {
+ AddMeterInputBuilder meterBuilder = new AddMeterInputBuilder();
+
+ meterBuilder.setContainerName(meterAddDataObject.getContainerName());
+ meterBuilder.setFlags(meterAddDataObject.getFlags());
+ meterBuilder.setMeterBandHeaders(meterAddDataObject.getMeterBandHeaders());
+ meterBuilder.setMeterId(meterAddDataObject.getMeterId());
+ meterBuilder.setNode(meterAddDataObject.getNode());
+ originalSwMeterView.put(meterKey, meterAddDataObject);
+ meterService.addMeter(meterBuilder.build());
+ }
+
+ originalSwMeterView.put(meterKey, meterAddDataObject);
+ }
+ else {
+ return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
+ }
+
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ /*
+ * Update Meter to the southbound plugin and our internal database
+ *
+ * @param path
+ * @param dataObject
+ */
+ private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
+ MeterKey meterKey = meterUpdateDataObject.getKey();
+
+ if (null != meterKey &&
+ validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
+ if (meterUpdateDataObject.isInstall()) {
+ UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();
+
+ originalSwMeterView.put(meterKey, meterUpdateDataObject);
+ meterService.updateMeter(updateMeterBuilder.build());
+ }
+
+ originalSwMeterView.put(meterKey, meterUpdateDataObject);
+ }
+ else {
+ return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
+ }
+
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ /*
+ * Remove Meter to the southbound plugin and our internal database
+ *
+ * @param path
+ * @param dataObject
+ */
+ private Status RemoveMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
+ MeterKey meterKey = meterUpdateDataObject.getKey();
+
+ if (null != meterKey &&
+ validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
+ if (meterUpdateDataObject.isInstall()) {
+ UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();
+
+ originalSwMeterView.put(meterKey, meterUpdateDataObject);
+ meterService.updateMeter(updateMeterBuilder.build());
+ }
+
+ originalSwMeterView.put(meterKey, meterUpdateDataObject);
+ }
+ else {
+ return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
+ }
+
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ public Status validateMeter(Meter meter, FRMUtil.operation operation) {
+ String containerName;
+ String meterName;
+ Status returnStatus = null;
+ boolean returnResult;
+
+ if (null != meter) {
+ containerName = meter.getContainerName();
+
+ if (null == containerName) {
+ containerName = GlobalConstants.DEFAULT.toString();
+ }
+ else if (!FRMUtil.isNameValid(containerName)) {
+ logger.error("Container Name is invalid %s" + containerName);
+ returnStatus = new Status(StatusCode.BADREQUEST, "Container Name is invalid");
+ return returnStatus;
+ }
+
+ meterName = meter.getMeterName();
+ if (!FRMUtil.isNameValid(meterName)) {
+ logger.error("Meter Name is invalid %s" + meterName);
+ returnStatus = new Status(StatusCode.BADREQUEST, "Meter Name is invalid");
+ return returnStatus;
+ }
+
+ returnResult = doesMeterEntryExists(meter.getKey(), meterName, containerName);
+
+ if (FRMUtil.operation.ADD == operation && returnResult) {
+ logger.error("Record with same Meter Name exists");
+ returnStatus = new Status(StatusCode.BADREQUEST, "Meter record exists");
+ return returnStatus;
+ }
+ else if (!returnResult) {
+ logger.error("Group record does not exist");
+ returnStatus = new Status(StatusCode.BADREQUEST, "Meter record does not exist");
+ return returnStatus;
+ }
+
+ for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
+ if (!meter.getFlags().isMeterBurst()) {
+ if (0 < meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBurstSize()) {
+ logger.error("Burst size should only be associated when Burst FLAG is set");
+ returnStatus = new Status(StatusCode.BADREQUEST, "Burst size should only be associated when Burst FLAG is set");
+ break;
+ }
+ }
+ }
+
+ if (null != returnStatus && !returnStatus.isSuccess()) {
+ return returnStatus;
+ }
+ else {
+ BandType setBandType = null;
+ DscpRemark dscpRemark = null;
+ for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
+ setBandType = meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBandType();
+ if ( setBandType instanceof DscpRemark) {
+ dscpRemark = (DscpRemark)setBandType;
+ if (0 > dscpRemark.getRate()) {
+
+ }
+ }
+ else if (setBandType instanceof Drop) {
+ if (0 < dscpRemark.getPercLevel()) {
+ logger.error("Number of drop Precedence level");
+ }
+ }
+ else if (setBandType instanceof Experimenter) {
+
+ }
+ }
+ }
+ }
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ private boolean doesMeterEntryExists(MeterKey key, String meterName, String containerName) {
+ if (! originalSwMeterView.containsKey(key)) {
+ return false;
+ }
+
+ for (Entry<MeterKey, Meter> entry : originalSwMeterView.entrySet()) {
+ if (entry.getValue().getMeterName().equals(meterName)) {
+ if (entry.getValue().getContainerName().equals(containerName)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
+ for(Entry<InstanceIdentifier<?>, Meter> entry :transaction.additions.entrySet()) {
+
+ if (!addMeter(entry.getKey(),entry.getValue()).isSuccess()) {
+ return Rpcs.getRpcResult(false, null, null);
+ }
+ }
+ for(@SuppressWarnings("unused") Entry<InstanceIdentifier<?>, Meter> entry :transaction.updates.entrySet()) {
+
+ if (!updateMeter(entry.getKey(),entry.getValue()).isSuccess()) {
+ return Rpcs.getRpcResult(false, null, null);
+ }
+ }
+
+ for(InstanceIdentifier<?> removal : transaction.removals) {
+ /* if (!removeMeter(entry.getKey(),entry.getValue()).isSuccess()) {
+ return Rpcs.getRpcResult(false, null, null);
+ }*/
+ }
+
+ return Rpcs.getRpcResult(true, null, null);
+ }
+
+ private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
+
+ private final DataModification<InstanceIdentifier<?>, DataObject> modification;
+
+ @Override
+ public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
+ return modification;
+ }
+
+ public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+ this.modification = modification;
+ }
+
+ Map<InstanceIdentifier<?>, Meter> additions = new HashMap<>();
+ Map<InstanceIdentifier<?>, Meter> updates = new HashMap<>();
+ Set<InstanceIdentifier<?>> removals = new HashSet<>();
+
+ /**
+ * We create a plan which flows will be added, which will be updated and
+ * which will be removed based on our internal state.
+ *
+ */
+ void prepareUpdate() {
+
+ Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
+ for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
+ if (entry.getValue() instanceof Meter) {
+ Meter Meter = (Meter) entry.getValue();
+ preparePutEntry(entry.getKey(), Meter);
+ }
+
+ }
+
+ removals = modification.getRemovedConfigurationData();
+ }
+
+ private void preparePutEntry(InstanceIdentifier<?> key, Meter meter) {
+
+ Meter original = originalSwMeterView.get(key);
+ if (original != null) {
+ // It is update for us
+
+ updates.put(key, meter);
+ } else {
+ // It is addition for us
+
+ additions.put(key, meter);
+ }
+ }
+
+ /**
+ * We are OK to go with execution of plan
+ *
+ */
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+
+ RpcResult<Void> rpcStatus = commitToPlugin(this);
+ // We return true if internal transaction is successful.
+ // return Rpcs.getRpcResult(true, null, Collections.emptySet());
+ return rpcStatus;
+ }
+
+ /**
+ *
+ * We should rollback our preparation
+ *
+ */
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ // NOOP - we did not modified any internal state during
+ // requestCommit phase
+ // return Rpcs.getRpcResult(true, null, Collections.emptySet());
+ return Rpcs.getRpcResult(true, null, null);
+
+ }
+
+ }
+
+ private final class MeterDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
+ @Override
+ public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
+ DataModification<InstanceIdentifier<?>, DataObject> modification) {
+ // We should verify transaction
+ System.out.println("Coming in MeterDataCommitHandler");
+ internalTransaction transaction = new internalTransaction(modification);
+ transaction.prepareUpdate();
+ return transaction;
+ }
+ }
+
+ final class MeterEventListener implements SalMeterListener {
+
+ List<MeterAdded> addedMeter = new ArrayList<>();
+ List<MeterRemoved> removeMeter = new ArrayList<>();
+ List<MeterUpdated> updatedMeter = new ArrayList<>();
+
+ @Override
+ public void onMeterAdded(MeterAdded notification) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onMeterRemoved(MeterRemoved notification) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onMeterUpdated(MeterUpdated notification) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+}
</parent>
<artifactId>compatibility-parent</artifactId>
<packaging>pom</packaging>
- <name>MD-SAL to AD-SAL Adaptation</name>
+ <name>MD-SAL to AD-SAL Adaptation Parent</name>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
return null;
}
- public static def toStatus(RpcResult<Void> result) {
+ public static def toStatus(RpcResult<?> result) {
if (result.isSuccessful()) {
return new Status(StatusCode.SUCCESS);
} else {
import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
-import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+
import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.VlanCfi
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.ControllerActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.DropActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAllActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.HwPathActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.LoopbackActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.OutputActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopVlanActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushVlanActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlDstActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlSrcActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlTypeActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNextHopActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwDstActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwSrcActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTosActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpDstActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpSrcActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanCfiActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanIdActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanPcpActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SwPathActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4Builder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6Builder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.ActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.ActionList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.VlanCfi;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.ControllerAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.DropAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAllAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.HwPathAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.LoopbackAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.OutputAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopMplsAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopVlanAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushMplsAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushPbbAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushVlanAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlTypeAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetMplsTtlAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNextHopAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTosAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTtlAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetQueueAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanCfiAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanIdAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanPcpAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SwPathAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.ActionList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetMplsTtlAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTtlAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
public static List<org.opendaylight.controller.sal.action.Action> actionFrom(List<Action> actions) {
List<org.opendaylight.controller.sal.action.Action> targetAction = new ArrayList<>();
for (Action action : actions) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.Action sourceAction = action
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action sourceAction = action
.getAction();
if (sourceAction instanceof ControllerAction) {
package org.opendaylight.controller.sal.compatibility.adsal;
+import java.math.BigInteger;
import java.util.concurrent.Future;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
}
@Override
- public Future<RpcResult<Void>> addFlow(AddFlowInput input) {
+ public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
Flow flow = ToSalConversionsUtils.toFlow(input);
@SuppressWarnings("unchecked")
org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
.getNode().getValue());
Status status = delegate.addFlowAsync(node, flow);
- Void rpcResultType = null;
+ AddFlowOutputBuilder builder = new AddFlowOutputBuilder();
+ builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
+ AddFlowOutput rpcResultType = builder.build();
return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
}
@Override
- public Future<RpcResult<Void>> removeFlow(RemoveFlowInput input) {
+ public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
Flow flow = ToSalConversionsUtils.toFlow(input);
@SuppressWarnings("unchecked")
org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
.getNode().getValue());
Status status = delegate.removeFlowAsync(node, flow);
- Void rpcResultType = null;
+ RemoveFlowOutputBuilder builder = new RemoveFlowOutputBuilder();
+ builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
+ RemoveFlowOutput rpcResultType = builder.build();
return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
}
@Override
- public Future<RpcResult<Void>> updateFlow(UpdateFlowInput input) {
+ public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
@SuppressWarnings("unchecked")
org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
.getNode().getValue());
Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow());
Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow());
Status status = delegate.modifyFlowAsync(node, originalFlow, updatedFlow);
- Void rpcResultType = null;
- return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+ UpdateFlowOutputBuilder builder = new UpdateFlowOutputBuilder();
+ builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
+ UpdateFlowOutput rpcResultType = builder.build();
+ throw new UnsupportedOperationException("Need to translate AD-SAL status to MD-SAL UpdateFlowOuptut - eaw@cisco.com");
+ // return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
}
}
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
}
private void checkOdActions(
- List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action> actions) {
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions) {
checkOdAction(actions, FloodAction.class, false);
checkOdAction(actions, FloodAllAction.class, false);
checkOdAction(actions, HwPathAction.class, false);
}
private void checkOdAction(
- List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action> actions, Class<?> cl,
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions, Class<?> cl,
boolean b) {
int numOfFoundActions = 0;
- for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action action : actions) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.Action innerAction = action
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action action : actions) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action innerAction = action
.getAction();
if (cl.isInstance(innerAction)) {
numOfFoundActions++;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.VlanCfi;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
--- /dev/null
+module opendaylight-action-types {
+ namespace "urn:opendaylight:action:types";
+ prefix action;
+
+ import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
+ import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
+ import opendaylight-l2-types {prefix l2t; revision-date "2013-08-27";}
+
+ revision "2013-11-12" {
+ description "Initial revision of action service";
+ }
+
+ typedef vlan-cfi {
+ type int32;
+ }
+
+ grouping address {
+ choice address {
+ case ipv4 {
+ leaf ipv4-address {
+ type inet:ipv4-prefix;
+ }
+ }
+ case ipv6 {
+ leaf ipv6-address {
+ type inet:ipv6-prefix;
+ }
+ }
+ }
+ }
+
+ grouping action-list {
+ list action {
+ key "order";
+ leaf order {
+ type int32;
+ }
+ uses action;
+ }
+ }
+
+ grouping action {
+ choice action {
+ case output-action {
+ leaf-list output-node-connector {
+ type inet:uri;
+ }
+
+ leaf max-length {
+ type uint16 {
+ range "0..65294";
+ }
+ }
+ }
+
+ case controller-action {
+ leaf max-length {
+ type uint16 {
+ range "0..65294";
+ }
+ }
+ }
+
+ case set-queue-action {
+ leaf queue {
+ type string;
+ }
+ }
+
+ case pop-mpls-action {
+ leaf ethernet-type {
+ type uint16; // TODO: define ethertype type
+ }
+ }
+
+ case set-mpls-ttl-action {
+ leaf mpls-ttl {
+ type uint8;
+ }
+ }
+
+ case set-nw-ttl-action {
+ leaf nw-ttl {
+ type uint8;
+ }
+ }
+
+ case push-pbb-action {
+ leaf ethernet-type {
+ type uint16; // TODO: define ethertype type
+ }
+ }
+
+ case pop-pbb-action {
+
+ }
+
+ case push-mpls-action {
+ leaf ethernet-type {
+ type uint16; // TODO: define ethertype type
+ }
+ }
+
+ case dec-mpls-ttl {
+ }
+
+ case dec-nw-ttl {
+ }
+
+ case drop-action {
+ }
+
+ case flood-action {
+ }
+
+ case flood-all-action {
+ }
+
+ case hw-path-action {
+ }
+
+ case loopback-action {
+ }
+
+ case pop-vlan-action {
+ }
+
+ case push-vlan-action {
+ leaf ethernet-type {
+ type uint16; // TODO: define ethertype type
+ }
+ leaf tag { // TPID - 16 bits
+ type int32;
+ }
+ leaf pcp { // PCP - 3 bits
+ type int32;
+ }
+ leaf cfi { // CFI - 1 bit (drop eligible)
+ type vlan-cfi;
+ }
+ leaf vlan-id { // VID - 12 bits
+ type l2t:vlan-id;
+ }
+// leaf tci { //TCI = [PCP + CFI + VID]
+// }
+// leaf header { //header = [TPID + TCI]
+// }
+ }
+
+ case copy-ttl-out {
+ }
+
+ case copy-ttl-in {
+ }
+
+ case set-dl-dst-action {
+ leaf address {
+ type yang:mac-address;
+ }
+ }
+
+ case set-dl-src-action {
+ leaf address {
+ type yang:mac-address;
+ }
+ }
+ case group-action {
+ leaf group {
+ type string;
+ }
+ }
+
+ case set-dl-type-action {
+ leaf dl-type {
+ type l2t:ether-type;
+ }
+ }
+
+ case set-next-hop-action {
+ uses address;
+ }
+
+ case set-nw-dst-action {
+ uses address;
+ }
+
+ case set-nw-src-action{
+ uses address;
+ }
+
+ case set-nw-tos-action {
+ leaf tos {
+ type int32;
+ }
+ }
+
+ case set-tp-dst-action {
+ leaf port {
+ type inet:port-number;
+ }
+ }
+ case set-tp-src-action {
+ leaf port {
+ type inet:port-number;
+ }
+ }
+ case set-vlan-cfi-action {
+ leaf vlan-cfi {
+ type vlan-cfi;
+ }
+ }
+
+ case set-vlan-id-action {
+ leaf vlan-id {
+ type l2t:vlan-id;
+ }
+ }
+
+ case set-vlan-pcp-action {
+ leaf vlan-pcp {
+ type l2t:vlan-pcp;
+ }
+ }
+
+ case sw-path-action {
+ }
+ }
+ }
+}
\ No newline at end of file
prefix flow;
import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
- import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
- import opendaylight-l2-types {prefix l2t; revision-date "2013-08-27";}
+ import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
import opendaylight-match-types {prefix match; revision-date 2013-10-26";}
-
+ import opendaylight-action-types {prefix action;}
revision "2013-10-26" {
description "Initial revision of flow service";
}
-
- typedef vlan-cfi {
- type int32;
- }
-
-
- grouping action-list {
- list action {
+ grouping instruction-list {
+ list instruction {
key "order";
leaf order {
type int32;
}
- uses action;
- }
- }
-
- grouping address {
- choice address {
- case ipv4 {
- leaf ipv4-address {
- type inet:ipv4-prefix;
- }
- }
- case ipv6 {
- leaf ipv6-address {
- type inet:ipv6-prefix;
- }
- }
+ uses instruction;
}
- }
-
- grouping instruction-list {
- list instruction {
- key "order";
- leaf order {
- type int32;
- }
- uses instruction;
- }
}
grouping instruction {
}
case write-actions {
- uses action-list;
+ uses action:action-list;
}
case apply-actions {
- uses action-list;
+ uses action:action-list;
}
case clear-actions {
- uses action-list;
+ uses action:action-list;
}
case meter {
}
}
- grouping action {
- choice action {
- case output-action {
- leaf-list output-node-connector {
- type inet:uri;
- }
-
- leaf max-length {
- type uint16 {
- range "0..65294";
- }
- }
- }
-
- case controller-action {
- leaf max-length {
- type uint16 {
- range "0..65294";
- }
- }
- }
-
- case set-queue-action {
- leaf queue {
- type string;
- }
- }
-
- case pop-mpls-action {
- leaf ethernet-type {
- type uint16; // TODO: define ethertype type
- }
- }
-
- case set-mpls-ttl-action {
- leaf mpls-ttl {
- type uint8;
- }
- }
-
- case set-nw-ttl-action {
- leaf nw-ttl {
- type uint8;
- }
- }
-
- case push-pbb-action {
- leaf ethernet-type {
- type uint16; // TODO: define ethertype type
- }
- }
-
- case pop-pbb-action {
-
- }
-
- case push-mpls-action {
- leaf ethernet-type {
- type uint16; // TODO: define ethertype type
- }
- }
-
- case dec-mpls-ttl {
- }
-
- case dec-nw-ttl {
- }
-
- case drop-action {
- }
-
- case flood-action {
- }
-
- case flood-all-action {
- }
-
- case hw-path-action {
- }
-
- case loopback-action {
- }
-
- case pop-vlan-action {
- }
-
- case push-vlan-action {
- leaf tag { // TPID - 16 bits
- type int32;
- }
- leaf pcp { // PCP - 3 bits
- type int32;
- }
- leaf cfi { // CFI - 1 bit (drop eligible)
- type vlan-cfi;
- }
- leaf vlan-id { // VID - 12 bits
- type l2t:vlan-id;
- }
-// leaf tci { //TCI = [PCP + CFI + VID]
-// }
-// leaf header { //header = [TPID + TCI]
-// }
- }
-
- case copy-ttl-out {
- }
-
- case copy-ttl-in {
- }
-
- case set-dl-dst-action {
- leaf address {
- type yang:mac-address;
- }
- }
-
- case set-dl-src-action {
- leaf address {
- type yang:mac-address;
- }
- }
- case group-action {
- leaf group {
- type string;
- }
- }
-
- case set-dl-type-action {
- leaf dl-type {
- type l2t:ether-type;
- }
- }
-
- case set-next-hop-action {
- uses address;
- }
-
- case set-nw-dst-action {
- uses address;
- }
-
- case set-nw-src-action{
- uses address;
- }
-
- case set-nw-tos-action {
- leaf tos {
- type int32;
- }
- }
-
- case set-tp-dst-action {
- leaf port {
- type inet:port-number;
- }
- }
- case set-tp-src-action {
- leaf port {
- type inet:port-number;
- }
- }
- case set-vlan-cfi-action {
- leaf vlan-cfi {
- type vlan-cfi;
- }
- }
-
- case set-vlan-id-action {
- leaf vlan-id {
- type l2t:vlan-id;
- }
- }
-
- case set-vlan-pcp-action {
- leaf vlan-pcp {
- type l2t:vlan-pcp;
- }
- }
-
- case sw-path-action {
- }
- }
- }
-
typedef flow-mod-flags {
type bits {
bit CHECK_OVERLAP;
bit RESET_COUNTS;
bit NO_PKT_COUNTS;
bit NO_BYT_COUNTS;
+ bit SEND_FLOW_REM;
}
}
leaf flow-name{
type string;
}
+
+ leaf installHw {
+ type boolean;
+ }
+
+ leaf barrier {
+ type boolean;
+ }
+
+ leaf strict {
+ type boolean;
+ default "false";
+ }
+
}
grouping flow-statistics {
prefix group;
import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
- import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
- import opendaylight-flow-types {prefix flow-types;revision-date 2013-10-26";}
+ import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
+ import opendaylight-action-types {prefix action;}
revision "2013-10-18" {
description "Initial revision of group service";
type string;
}
+ leaf install {
+ type boolean;
+ }
+
leaf barrier {
type boolean;
}
type uint32;
}
- container actions {
- list action {
- key "action-order";
- leaf action-order {
- type int32;
- }
-
- uses flow-types:action;
- }
- }
+ uses action:action-list;
}
}
}
}
uses group-types;
+
leaf capabilities {
type enumeration {
enum select-weight;
type binary;
}
}
+
+ grouping "of-metadata" {
+ leaf metadata {
+ type uint64;
+ }
+
+ leaf metadata-mask {
+ type binary;
+ }
+ }
/** Match Groupings **/
grouping "ethernet-match-fields" {
mandatory true;
type l2t:ether-type; // Needs to define that as general model
}
+
leaf mask {
type binary;
}
description "IP Proto (IPv4 or IPv6 Protocol Number).";
type inet:ip-version;
}
- }
-
+ }
+
grouping "ipv4-match-fields" {
leaf ipv4-source {
description "IPv4 source address.";
type inet:ipv4-prefix;
}
+
leaf ipv4-destination {
description "IPv4 destination address.";
type inet:ipv4-prefix;
}
+
}
-
+
grouping "ipv6-match-fields" {
leaf ipv6-source {
description "IPv6 source address.";
type inet:ipv6-prefix;
}
-
+
leaf ipv6-destination {
description "IPv6 destination address.";
type inet:ipv6-prefix;
leaf ipv6-nd-target {
description "IPv6 target address for neighbour discovery message";
- type inet:ipv6-prefix;
+ type inet:ipv6-address;
}
- leaf ipv6-flabel {
- type inet:ipv6-flow-label;
+ container "ipv6-label" {
+ leaf ipv6-flabel {
+ type inet:ipv6-flow-label;
+ }
+
+ leaf flabel-mask {
+ type binary;
+ }
}
leaf ipv6-nd-sll {
type uint8;
}
- leaf pbb-isid {
- description "I-SID in the first PBB service instance tag";
- type uint32;
- }
-
+ container "pbb" {
+ leaf pbb-isid {
+ description "I-SID in the first PBB service instance tag";
+ type uint32;
+ }
+
+ leaf pbb-mask {
+ type binary;
+ }
+ }
}
grouping "tcp-match-fields" {
type uint32;
}
- leaf metadata {
- type uint64;
+ container "metadata" {
+ uses of-metadata;
}
- leaf tunnel-id {
- description "Metadata associated in the logical port";
- type uint64;
+ container "tunnel" {
+ leaf tunnel-id {
+ description "Metadata associated in the logical port";
+ type uint64;
+ }
+
+ leaf tunnel-mask {
+ type binary;
+ }
}
container "ethernet-match" {
uses meter-band-type;
}
+ leaf rate {
+ type uint32;
+ }
+
leaf burst-size {
type uint32;
}
import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
import opendaylight-flow-types {prefix flow;revision-date 2013-10-26";}
-
+ import opendaylight-action-types {prefix action;}
revision "2013-10-26" {
description "Initial revision of table service";
case write-actions {
container write-actions {
- uses flow:action-list;
+ uses action:action-list;
}
}
case write-actions-miss {
container write-actions-miss {
- uses flow:action-list;
+ uses action:action-list;
}
}
case apply-actions {
container apply-actions {
- uses flow:action-list;
+ uses action:action-list;
}
}
case apply-actions-miss {
container apply-actions-miss {
- uses flow:action-list;
+ uses action:action-list;
}
}
import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
import opendaylight-flow-types {prefix types;revision-date "2013-10-26";}
-
+ import flow-capable-transaction {prefix tr;}
revision "2013-08-19" {
description "Initial revision of flow service";
}
-
typedef flow-table-ref {
type instance-identifier;
}
rpc add-flow {
input {
uses node-flow;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
rpc remove-flow {
input {
uses node-flow;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
rpc update-flow {
input {
uses flow-update;
+ uses tr:transaction-aware;
+ }
+ output {
+ uses tr:transaction-aware;
}
}
org.opendaylight.controller.sal.binding.impl.*,
org.opendaylight.controller.sal.binding.codegen,
org.opendaylight.controller.sal.binding.codegen.*,
+ org.opendaylight.controller.sal.binding.dom.*,
</Private-Package>
</instructions>
</configuration>
*/
package org.opendaylight.controller.sal.binding.codegen;
-import org.opendaylight.controller.sal.binding.spi.DelegateProxy;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
import org.opendaylight.controller.sal.binding.spi.RpcRouter;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.RpcImplementation;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
+++ /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.codegen.impl;
-
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-
-public class JavassistUtils {
-
- public static interface ClassGenerator {
- void process(CtClass cls);
- }
-
- public static interface MethodGenerator {
- void process(CtMethod method);
- }
-
- public static interface FieldGenerator {
- void process(CtField field);
- }
-}
import javassist.CtClass
import static com.google.common.base.Preconditions.*
-
-import javassist.CtField
-import javassist.Modifier
import javassist.CtMethod
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
import java.util.Map
import java.util.HashMap
-import javassist.NotFoundException
-import javassist.LoaderClassPath
-import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.MethodGenerator
-import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.ClassGenerator
+
+
import org.opendaylight.yangtools.yang.binding.NotificationListener
import org.opendaylight.yangtools.yang.binding.Notification
-import java.util.Arrays
+
import static extension org.opendaylight.controller.sal.binding.codegen.YangtoolsMappingHelper.*
import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.*
import java.util.Set
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper
import java.util.WeakHashMap
-import javassist.ClassClassPath
import org.opendaylight.yangtools.yang.binding.annotations.QName
import org.opendaylight.yangtools.yang.binding.DataContainer
import org.opendaylight.yangtools.yang.binding.RpcImplementation
+import org.opendaylight.controller.sal.binding.codegen.util.JavassistUtils
class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator, NotificationInvokerFactory {
val CtClass BROKER_NOTIFICATION_LISTENER;
val ClassPool classPool;
+ val extension JavassistUtils utils;
val Map<Class<? extends NotificationListener>, RuntimeGeneratedInvokerPrototype> invokerClasses;
public new(ClassPool pool) {
classPool = pool;
+ utils = new JavassistUtils(pool);
invokerClasses = new WeakHashMap();
BROKER_NOTIFICATION_LISTENER = org.opendaylight.controller.sal.binding.api.NotificationListener.asCtClass;
}
finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener>);
}
- private def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
- val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
- function1.process(method);
- it.addMethod(method);
- }
-
- private def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
- for (method : source.methods) {
- if (method.declaringClass == source) {
- val redeclaredMethod = new CtMethod(method, target, null);
- function1.process(redeclaredMethod);
- target.addMethod(redeclaredMethod);
- }
- }
- }
-
- private def CtClass createClass(String fqn, ClassGenerator cls) {
- val target = classPool.makeClass(fqn);
- cls.process(target);
- return target;
- }
-
- private def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
- val target = classPool.makeClass(fqn);
- target.implementsType(superInterface);
- cls.process(target);
- return target;
- }
-
- private def void implementsType(CtClass it, CtClass supertype) {
- checkArgument(supertype.interface, "Supertype must be interface");
- addInterface(supertype);
- }
-
- private def asCtClass(Class<?> class1) {
- classPool.get(class1);
- }
+
- private def CtField field(CtClass it, String name, Class<?> returnValue) {
- val field = new CtField(returnValue.asCtClass, name, it);
- field.modifiers = Modifier.PUBLIC
- addField(field);
- return field;
- }
- def get(ClassPool pool, Class<?> cls) {
- try {
- return pool.get(cls.name)
- } catch (NotFoundException e) {
- pool.appendClassPath(new LoaderClassPath(cls.classLoader));
- try {
- return pool.get(cls.name)
-
- } catch (NotFoundException ef) {
- pool.appendClassPath(new ClassClassPath(cls));
- return pool.get(cls.name)
- }
- }
- }
protected def resolveInvokerClass(Class<? extends NotificationListener> class1) {
val invoker = invokerClasses.get(class1);
--- /dev/null
+package org.opendaylight.controller.sal.binding.codegen.util;
+
+import javassist.CtClass;
+
+public interface ClassGenerator {
+ void process(CtClass cls);
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.codegen.util;
+
+import javassist.CtField;
+
+public interface FieldGenerator {
+ void process(CtField field);
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.codegen.util
+
+import javassist.CtClass
+import javassist.CtMethod
+import javassist.ClassPool
+import java.util.Arrays
+import static com.google.common.base.Preconditions.*;
+import javassist.CtField
+import javassist.Modifier
+import javassist.NotFoundException
+import javassist.LoaderClassPath
+import javassist.ClassClassPath
+
+class JavassistUtils {
+
+ ClassPool classPool
+
+ new(ClassPool pool) {
+ classPool = pool;
+ }
+
+ def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
+ val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
+ function1.process(method);
+ it.addMethod(method);
+ }
+
+ def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter1, Class<?> parameter2, MethodGenerator function1) {
+ val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter1.asCtClass,parameter2.asCtClass), it);
+ function1.process(method);
+ it.addMethod(method);
+ }
+
+
+ def void staticMethod(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
+ val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
+ function1.process(method);
+ it.addMethod(method);
+ }
+
+ def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
+ for (method : source.methods) {
+ if (method.declaringClass == source) {
+ val redeclaredMethod = new CtMethod(method, target, null);
+ function1.process(redeclaredMethod);
+ target.addMethod(redeclaredMethod);
+ }
+ }
+ }
+
+ def CtClass createClass(String fqn, ClassGenerator cls) {
+ val target = classPool.makeClass(fqn);
+ cls.process(target);
+ return target;
+ }
+
+ def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
+ val target = classPool.makeClass(fqn);
+ target.implementsType(superInterface);
+ cls.process(target);
+ return target;
+ }
+
+ def void implementsType(CtClass it, CtClass supertype) {
+ checkArgument(supertype.interface, "Supertype must be interface");
+ addInterface(supertype);
+ }
+
+ def asCtClass(Class<?> class1) {
+ classPool.get(class1);
+ }
+
+ def CtField field(CtClass it, String name, Class<?> returnValue) {
+ val field = new CtField(returnValue.asCtClass, name, it);
+ field.modifiers = Modifier.PUBLIC
+ addField(field);
+ return field;
+ }
+
+ def get(ClassPool pool, Class<?> cls) {
+ try {
+ return pool.get(cls.name)
+ } catch (NotFoundException e) {
+ pool.appendClassPath(new LoaderClassPath(cls.classLoader));
+ try {
+ return pool.get(cls.name)
+
+ } catch (NotFoundException ef) {
+ pool.appendClassPath(new ClassClassPath(cls));
+ return pool.get(cls.name)
+ }
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.codegen.util;
+
+import javassist.CtMethod;
+
+public interface MethodGenerator {
+ void process(CtMethod method);
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.dom.serializer.impl
+
+import javassist.ClassPool
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import org.opendaylight.controller.sal.binding.codegen.util.JavassistUtils
+import javassist.CtClass
+import java.util.Map
+import org.opendaylight.yangtools.yang.common.QName
+import javassist.CtField
+import static javassist.Modifier.*
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.binding.generator.util.Types
+import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
+import java.util.HashMap
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
+import java.util.WeakHashMap
+import java.util.List
+import java.util.TreeSet
+import com.google.common.base.Joiner
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*;
+import org.opendaylight.yangtools.yang.binding.BindingDeserializer
+import org.opendaylight.yangtools.yang.binding.BindingSerializer
+import org.opendaylight.yangtools.yang.binding.BindingCodec
+import org.slf4j.LoggerFactory
+
+class TransformerGenerator {
+
+ private static val log = LoggerFactory.getLogger(TransformerGenerator)
+
+ public static val STRING = Types.typeForClass(String);
+ public static val BOOLEAN = Types.typeForClass(Boolean);
+ public static val INTEGER = Types.typeForClass(Integer);
+
+ //public static val DECIMAL = Types.typeForClass(Decimal);
+ public static val LONG = Types.typeForClass(Long);
+
+ val ClassPool classPool
+ val extension JavassistUtils utils;
+
+ CtClass ctTransformator
+
+ CtClass ctQName
+
+ @Property
+ var Map<Type, Type> typeDefinitions;
+
+ @Property
+ var Map<Type, GeneratedTypeBuilder> typeToDefinition
+
+ @Property
+ var Map<Type, SchemaNode> typeToSchemaNode
+
+ val Map<Class<?>, Class<?>> generatedClasses = new WeakHashMap();
+
+ public new(ClassPool pool) {
+ classPool = pool;
+ utils = new JavassistUtils(pool)
+
+ ctTransformator = BindingCodec.asCtClass;
+ ctQName = QName.asCtClass
+ }
+
+ def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
+ return withClassLoader(inputType.classLoader) [ |
+ val ret = generatedClasses.get(inputType);
+ if (ret !== null) {
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ }
+ val ref = Types.typeForClass(inputType)
+ val node = typeToSchemaNode.get(ref)
+ val typeSpecBuilder = typeToDefinition.get(ref)
+ val typeSpec = typeSpecBuilder.toInstance();
+ val newret = generateTransformerFor(inputType, typeSpec, node)
+ generatedClasses.put(inputType, newret);
+ return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ ]
+ }
+
+ def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
+ return withClassLoader(inputType.classLoader) [ |
+ val transformer = generatedClasses.get(inputType);
+ if (transformer != null) {
+ return transformer;
+ }
+ val newret = generateKeyTransformerFor(inputType, type, schema);
+ generatedClasses.put(inputType, newret);
+ return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ ]
+ }
+
+ def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
+ val cls = loadClassWithTCCL(type.resolvedName + "Key");
+ keyTransformerFor(cls, type, node);
+ }
+
+ private def serializer(Type type) {
+ val cls = loadClassWithTCCL(type.resolvedName);
+ transformerFor(cls);
+
+ }
+
+ def Class<?> getValueSerializer(GeneratedTransferObject type) {
+ val cls = loadClassWithTCCL(type.resolvedName);
+ val transformer = generatedClasses.get(cls);
+ if (transformer !== null) {
+ return transformer;
+ }
+ val valueTransformer = generateValueTransformer(cls, type);
+ generatedClasses.put(cls, valueTransformer);
+ return valueTransformer;
+ }
+
+ private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
+ try {
+ log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+ val properties = typeSpec.allProperties;
+ val ctCls = createClass(inputType.transformatorFqn) [
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ staticQNameField(node.QName);
+ implementsType(ctTransformator)
+ method(Object, "toDomStatic", QName, Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ {
+
+ return null;
+ }
+ '''
+ ]
+ method(Object, "fromDomStatic", QName, Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ {
+ if($2 == null){
+ return null;
+ }
+ «QName.name» _localQName = $1;
+ java.util.Map _compositeNode = (java.util.Map) $2;
+ «FOR key : node.keyDefinition»
+ «val propertyName = key.getterName»
+ «val keyDef = node.getDataChildByName(key)»
+ «val property = properties.get(propertyName)»
+ «deserializeProperty(keyDef, property.returnType, property)»;
+ «ENDFOR»
+ «inputType.name» _value = new «inputType.name»(«node.keyDefinition.keyConstructorList»);
+ return _value;
+ }
+ '''
+ ]
+ method(Object, "serialize", Object) [
+ body = '''
+ return toDomStatic(QNAME,$1);
+ '''
+ ]
+ method(Object, "deserialize", Object) [
+ body = '''
+ return fromDomStatic(QNAME,$1);
+ '''
+ ]
+ ]
+ val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ log.info("DOM Codec for {} was generated {}",inputType,ret)
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
+ } catch (Exception e) {
+ log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+ val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+ exception.addSuppressed(e);
+ throw exception;
+ }
+ }
+
+ private def <D> Class<? extends BindingCodec<Map<QName, Object>, D>> generateTransformerFor(Class<D> inputType,
+ GeneratedType typeSpec, SchemaNode node) {
+ try {
+ log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+ val ctCls = createClass(typeSpec.transformatorFqn) [
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ staticQNameField(inputType);
+ implementsType(ctTransformator)
+ method(Object, "toDomStatic", QName, Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = serializeBodyFacade(typeSpec, node)
+ ]
+ method(Object, "serialize", Object) [
+ body = '''
+ return toDomStatic(QNAME,$1);
+ '''
+ ]
+ method(Object, "fromDomStatic", QName, Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = deserializeBody(typeSpec, node)
+ ]
+ method(Object, "deserialize", Object) [
+ body = '''
+ return fromDomStatic(QNAME,$1);
+ '''
+ ]
+ ]
+
+ val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, D>>;
+ } catch (Exception e) {
+ log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+ val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+ exception.addSuppressed(e);
+ throw exception;
+ }
+ }
+
+ private def keyConstructorList(List<QName> qnames) {
+ val names = new TreeSet<String>()
+ for (name : qnames) {
+ val fieldName = name.getterName;
+ names.add(fieldName);
+ }
+ return Joiner.on(",").join(names);
+ }
+
+ private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
+ val ret = serializeBody(type, node);
+ return ret;
+ }
+
+ private def String deserializeBody(GeneratedType type, SchemaNode node) {
+ val ret = deserializeBodyImpl(type, node);
+ return ret;
+ }
+
+ private def deserializeKey(GeneratedType type, ListSchemaNode node) {
+ if (node.keyDefinition != null && !node.keyDefinition.empty) {
+ return '''
+ «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
+ _builder.setKey(getKey);
+ ''';
+ }
+ }
+
+ private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
+ {
+ «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+
+ if($2 == null) {
+ return null;
+ }
+ java.util.Map _compositeNode = (java.util.Map) $2;
+ «type.builderName» _builder = new «type.builderName»();
+
+ return _builder.build();
+ }
+ '''
+
+ private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
+ {
+ «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+ if($2 == null) {
+ return null;
+ }
+ java.util.Map _compositeNode = (java.util.Map) $2;
+ «type.builderName» _builder = new «type.builderName»();
+ «deserializeKey(type, node)»
+ «deserializeDataNodeContainerBody(type, node)»
+ return _builder.build();
+ }
+ '''
+
+ private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) '''
+ {
+ «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+ if($2 == null) {
+ return null;
+ }
+ java.util.Map _compositeNode = (java.util.Map) $2;
+ «type.builderName» _builder = new «type.builderName»();
+ «deserializeDataNodeContainerBody(type, node)»
+ return _builder.build();
+ }
+ '''
+
+ private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) '''
+ {
+ «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+ if($2 == null) {
+ return null;
+ }
+ java.util.Map _compositeNode = (java.util.Map) $2;
+ «type.builderName» _builder = new «type.builderName»();
+ «deserializeDataNodeContainerBody(type, node)»
+ return _builder.build();
+ }
+ '''
+
+ private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
+ deserializeNodeContainerBodyImpl(type, type.allProperties, node);
+ }
+
+ private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, MethodSignature> properties,
+ DataNodeContainer node) {
+ val ret = '''
+ «FOR child : node.childNodes.filter[!augmenting]»
+ «val signature = properties.get(child.getterName)»
+ «deserializeProperty(child, signature.returnType, signature)»
+ _builder.«signature.name.toSetter»(«signature.name»);
+ «ENDFOR»
+ '''
+ return ret;
+ }
+
+ private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
+ MethodSignature property) '''
+ java.util.List _dom_«property.name» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
+ localName»"));
+ //System.out.println("«property.name»#deCode"+_dom_«property.name»);
+ java.util.List «property.name» = new java.util.ArrayList();
+ if(_dom_«property.name» != null) {
+ java.util.List _serialized = new java.util.ArrayList();
+ java.util.Iterator _iterator = _dom_«property.name».iterator();
+ boolean _hasNext = _iterator.hasNext();
+ while(_hasNext) {
+ Object _listItem = _iterator.next();
+ //System.out.println(" item" + _listItem);
+ Object _value = «type.actualTypeArguments.get(0).serializer.name».fromDomStatic(_localQName,_listItem);
+ //System.out.println(" value" + _value);
+ «property.name».add(_value);
+ _hasNext = _iterator.hasNext();
+ }
+ }
+
+ //System.out.println(" list" + «property.name»);
+ '''
+
+ private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
+ MethodSignature property) '''
+ java.util.List _dom_«property.name» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
+ localName»"));
+ java.util.List «property.name» = new java.util.ArrayList();
+ if(_dom_«property.name» != null) {
+ java.util.List _serialized = new java.util.ArrayList();
+ java.util.Iterator _iterator = _dom_«property.name».iterator();
+ boolean _hasNext = _iterator.hasNext();
+ while(_hasNext) {
+ Object _listItem = _iterator.next();
+ if(_listItem instanceof java.util.Map.Entry) {
+ Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
+ Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue")»;
+ «property.name».add(_value);
+ }
+ _hasNext = _iterator.hasNext();
+ }
+ }
+ '''
+
+ private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, MethodSignature property) '''
+ java.util.List _dom_«property.name»_list =
+ _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
+ «type.resolvedName» «property.name» = null;
+ if(_dom_«property.name»_list != null && _dom_«property.name»_list.size() > 0) {
+ java.util.Map.Entry _dom_«property.name» = (java.util.Map.Entry) _dom_«property.name»_list.get(0);
+ Object _inner_value = _dom_«property.name».getValue();
+ «property.name» = «deserializeValue(type, "_inner_value")»;
+ }
+ '''
+
+ private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
+ MethodSignature property) '''
+ java.util.List _dom_«property.name»_list =
+ _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
+ «type.resolvedName» «property.name» = null;
+ if(_dom_«property.name»_list != null && _dom_«property.name»_list.size() > 0) {
+
+ java.util.Map _dom_«property.name» = (java.util.Map) _dom_«property.name»_list.get(0);
+ «type.resolvedName» «property.name» = «type.serializer.name».fromDomStatic(_localQName,_dom_«property.name»);
+ }
+ '''
+
+ private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter) '''
+ («type.resolvedName») «type.valueSerializer.name».fromDomValue(«domParameter»);
+ '''
+
+ private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+ Class<?> inputType, GeneratedTransferObject typeSpec) {
+ try {
+
+ val returnType = typeSpec.valueReturnType;
+ if (returnType == null) {
+
+ val ctCls = createDummyImplementation(inputType, typeSpec);
+ val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ }
+ val ctCls = createClass(typeSpec.transformatorFqn) [
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ implementsType(ctTransformator)
+ implementsType(BindingDeserializer.asCtClass)
+ method(Object, "toDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ {
+ ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
+
+ if($1 == null) {
+ return null;
+ }
+ «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
+ //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
+ «returnType.resolvedName» _value = _encapsulatedValue.getValue();
+ //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
+ return _value;
+ }
+ '''
+ ]
+ method(Object, "serialize", Object) [
+ body = '''
+ {
+ return toDomValue($1);
+ }
+ '''
+ ]
+ method(Object, "fromDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ {
+ //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
+
+ if($1 == null) {
+ return null;
+ }
+ «returnType.name» _simpleValue = «deserializeValue(returnType, "$1")»;
+ «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
+ return _value;
+ }
+ '''
+ ]
+ method(Object, "deserialize", Object) [
+ body = '''{
+ return fromDomValue($1);
+ }
+ '''
+ ]
+ ]
+
+ val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ log.info("DOM Codec for {} was generated {}",inputType,ret)
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ } catch (Exception e) {
+ log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+ val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+ exception.addSuppressed(e);
+ throw exception;
+ }
+
+ }
+
+ private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
+ log.info("Generating Dummy DOM Codec for {} with {}",object,object.classLoader)
+ return createClass(typeSpec.transformatorFqn) [
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ implementsType(ctTransformator)
+ implementsType(BindingDeserializer.asCtClass)
+ method(Object, "toDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''return null;'''
+ ]
+ method(Object, "serialize", Object) [
+ body = '''
+ {
+ return toDomValue($1);
+ }
+ '''
+ ]
+ method(Object, "fromDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''return null;'''
+ ]
+ method(Object, "deserialize", Object) [
+ body = '''{
+ return fromDomValue($1);
+ }
+ '''
+ ]
+ ]
+ }
+
+ def Type getValueReturnType(GeneratedTransferObject object) {
+ for (prop : object.properties) {
+ if (prop.name == "value") {
+ return prop.returnType;
+ }
+ }
+ if (object.superType != null) {
+ return getValueReturnType(object.superType);
+ }
+ return null;
+ }
+
+ private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+ Class<?> inputType, Enumeration typeSpec) {
+ try {
+ log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+ val ctCls = createClass(typeSpec.transformatorFqn) [
+ //staticField(Map,"AUGMENTATION_SERIALIZERS");
+ implementsType(ctTransformator)
+ method(Object, "toDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ if($1 == null) {
+ return null;
+ }
+ «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
+ return _value.getValue();
+ '''
+ ]
+ method(Object, "serialize", Object) [
+ body = '''
+ return toDomValue($1);
+ '''
+ ]
+ method(Object, "fromDomValue", Object) [
+ modifiers = PUBLIC + FINAL + STATIC
+ body = '''
+ if($1 == null) {
+ return null;
+ }
+ _simpleValue = null;
+ «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(null);
+ return _value;
+ '''
+ ]
+ method(Object, "deserialize", Object) [
+ body = '''
+ return fromDomValue($1);
+ '''
+ ]
+ ]
+
+ val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+ log.info("DOM Codec for {} was generated {}",inputType,ret)
+ return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ } catch (Exception e) {
+ log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+ val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+ exception.addSuppressed(e);
+ throw exception;
+ }
+
+ }
+
+ private def dispatch String deserializeValue(Type type, String domParameter) '''(«type.resolvedName») «domParameter»'''
+
+ /**
+ * Default catch all
+ *
+ **/
+ private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, MethodSignature property) '''
+ «type.resolvedName» «property.name» = null;
+ '''
+
+ private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
+ MethodSignature property) {
+ _deserializeProperty(container, type.toInstance, property)
+ }
+
+ public static def toSetter(String it) {
+
+ if (startsWith("is")) {
+ return "set" + substring(2);
+ } else if (startsWith("get")) {
+ return "set" + substring(3);
+ }
+ return "set" + it;
+ }
+
+ /*
+ private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, MethodSignature property) '''
+ «property.returnType.resolvedName» «property.name» = value.«property.name»();
+ if(«property.name» != null) {
+ Object domValue = «type.serializer».toDomStatic(QNAME,«property.name»);
+ childNodes.add(domValue);
+ }
+ '''
+ */
+ private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
+
+ private def staticQNameField(CtClass it, Class node) {
+ val field = new CtField(ctQName, "QNAME", it);
+ field.modifiers = PUBLIC + FINAL + STATIC;
+ addField(field, '''«node.name».QNAME''')
+ }
+
+ private def staticQNameField(CtClass it, QName node) {
+ val field = new CtField(ctQName, "QNAME", it);
+ field.modifiers = PUBLIC + FINAL + STATIC;
+ addField(field, '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
+ }
+
+ private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) '''
+ {
+ «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
+ java.util.List childNodes = new java.util.ArrayList();
+ «type.resolvedName» value = («type.resolvedName») $2;
+ «transformDataContainerBody(type.allProperties, node)»
+ return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+ }
+ '''
+
+ private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) '''
+ {
+ «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
+ java.util.List childNodes = new java.util.ArrayList();
+ «type.resolvedName» value = («type.resolvedName») $2;
+ «transformDataContainerBody(type.allProperties, node)»
+ return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+ }
+ '''
+
+ private def transformDataContainerBody(Map<String, MethodSignature> properties, DataNodeContainer node) {
+ val ret = '''
+ «FOR child : node.childNodes.filter[!augmenting]»
+ «val signature = properties.get(child.getterName)»
+ «serializeProperty(child, signature.returnType, signature)»
+ «ENDFOR»
+ '''
+ return ret;
+ }
+
+ private static def String getGetterName(DataSchemaNode node) {
+ return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
+ }
+
+ private static def String getGetterName(QName node) {
+ return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
+ }
+
+ private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
+ MethodSignature property) '''
+ «property.returnType.resolvedName» «property.name» = value.«property.name»();
+ if(«property.name» != null) {
+ java.util.Iterator _iterator = «property.name».iterator();
+ boolean _hasNext = _iterator.hasNext();
+ while(_hasNext) {
+ Object _listItem = _iterator.next();
+ Object _domValue = «type.actualTypeArguments.get(0).serializer.name».toDomStatic(QNAME,_listItem);
+ childNodes.add(_domValue);
+ _hasNext = _iterator.hasNext();
+ }
+ }
+ '''
+
+ private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, MethodSignature property) '''
+ «property.returnType.resolvedName» «property.name» = value.«property.name»();
+
+ if(«property.name» != null) {
+ «QName.name» _qname = «QName.name».create(resultName,"«schema.QName.localName»");
+ Object _propValue = «serializeValue(type, property.name)»;
+ if(_propValue != null) {
+ Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
+ childNodes.add(_domValue);
+ }
+ }
+ '''
+
+ private def dispatch serializeValue(GeneratedTransferObject type, String parameter) '''«type.valueSerializer.name».toDomValue(«parameter»)'''
+
+ private def dispatch serializeValue(Type signature, String property) '''«property»'''
+
+ private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, Type type, MethodSignature property) '''
+ «property.returnType.resolvedName» «property.name» = value.«property.name»();
+ if(«property.name» != null) {
+ «QName.name» _qname = «QName.name».create(resultName,"«schema.QName.localName»");
+ java.util.Iterator _iterator = «property.name».iterator();
+ boolean _hasNext = _iterator.hasNext();
+ while(_hasNext) {
+ Object _listItem = _iterator.next();
+ Object _propValue = «property.name»;
+ Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
+ childNodes.add(_domValue);
+ _hasNext = _iterator.hasNext();
+ }
+ }
+ '''
+
+ /**
+ * Default catch all
+ *
+ **/
+ private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, MethodSignature property) '''
+ «property.returnType.resolvedName» «property.name» = value.«property.name»();
+ if(«property.name» != null) {
+ Object domValue = «property.name»;
+ childNodes.add(domValue);
+ }
+ '''
+
+ private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
+ MethodSignature property) {
+ serializeProperty(container, type.toInstance, property)
+ }
+
+ private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
+ MethodSignature property) '''
+ «property.returnType.resolvedName» «property.name» = value.«property.name»();
+ if(«property.name» != null) {
+ Object domValue = «type.serializer».toDomStatic(QNAME,«property.name»);
+ childNodes.add(domValue);
+ }
+ '''
+
+ private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
+ {
+ return ($r) java.util.Collections.singletonMap(this.QNAME,null);
+ }
+ '''
+
+ private def transformatorFqn(GeneratedType typeSpec) {
+ return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
+ }
+
+ private def transformatorFqn(Class typeSpec) {
+ return '''«typeSpec.name»$Broker$Codec$DOM'''
+ }
+
+ private def HashMap<String, MethodSignature> getAllProperties(GeneratedType type) {
+ val ret = new HashMap<String, MethodSignature>();
+ type.collectAllProperties(ret);
+ return ret;
+ }
+
+ private def dispatch void collectAllProperties(GeneratedType type, Map<String, MethodSignature> set) {
+ for (definition : type.methodDefinitions) {
+ set.put(definition.name, definition);
+ }
+
+ for (parent : type.implements) {
+ parent.collectAllProperties(set);
+ }
+ }
+
+ private def dispatch void collectAllProperties(Type type, Map<String, MethodSignature> set) {
+ // NOOP for generic type.
+ }
+
+ def String getResolvedName(Type type) {
+ return type.asCtClass.name;
+ }
+
+ def CtClass asCtClass(Type type) {
+ val name = type.fullyQualifiedName
+ val cls = loadClassWithTCCL(type.fullyQualifiedName)
+ return cls.asCtClass;
+ }
+
+}
+
+@Data
+class PropertyPair {
+
+ String getterName;
+
+ Type type;
+
+ @Property
+ MethodSignature signature;
+ @Property
+ SchemaNode schemaNode;
+}
import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
+import com.google.common.collect.HashMultimap
+import com.google.common.collect.ArrayListMultimap
+import com.google.common.collect.Multimap
+import java.util.Collection
+import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
class BindingMapping {
+
+
+ @Property
val Map<Type, GeneratedTypeBuilder> typeToDefinition = new HashMap();
+
+ @Property
val Map<Type, SchemaNode> typeToSchemaNode = new HashMap();
def QName getSchemaNode(Class<?> cls) {
}
- def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument, Class<? extends DataObject> parent) {
+ private def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument, Class<? extends DataObject> parent) {
val Class rawType = argument.type;
val ref = Types.typeForClass(rawType);
val schemaType = typeToSchemaNode.get(ref);
return new NodeIdentifierWithPredicates(qname, predicates);
}
- def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
+ private def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
val ref = Types.typeForClass(argument.type);
val qname = typeToSchemaNode.get(ref).QName
return new NodeIdentifier(qname);
}
- def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
+ private def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
val keyDefinitions = node.keyDefinition;
val map = new HashMap<QName, Object>();
for (keydef : keyDefinitions) {
return Collections.emptyList();
}
- def getSimpleValues(DataContainer container, LeafListSchemaNode node) {
+ private def getSimpleValues(DataContainer container, LeafListSchemaNode node) {
return Collections.emptyList();
}
return it;
}
- private def dispatch Node<?> getSimpleValue(Object container, QName name, ExtendedType type) {
+ public static def dispatch Node<?> getSimpleValue(Object container, QName name, ExtendedType type) {
getSimpleValue(container, name, type.baseType);
}
- private def dispatch Node<?> getSimpleValue(Object container, QName name, StringTypeDefinition type) {
+ public static def dispatch Node<?> getSimpleValue(Object container, QName name, StringTypeDefinition type) {
val value = container.getValue(name, String);
if(value === null) return null;
return new SimpleNodeTOImpl(name, null, value);
}
- private def dispatch Node<?> getSimpleValue(Object container, QName name, TypeDefinition<?> type) {
+ public static def dispatch Node<?> getSimpleValue(Object container, QName name, TypeDefinition<?> type) {
val value = container.getValue(name, Object);
if(value === null) return null;
return new SimpleNodeTOImpl(name, null, value);
}
- private def dispatch Node<?> getSimpleValue(Object container, QName name, BooleanTypeDefinition type) {
+ public static def dispatch Node<?> getSimpleValue(Object container, QName name, BooleanTypeDefinition type) {
val value = container.getValue(name, Boolean);
if(value === null) return null;
return new SimpleNodeTOImpl(name, null, value);
}
- private def dispatch Node<?> getSimpleValue(Object container, QName name, BinaryTypeDefinition type) {
+ public static def dispatch Node<?> getSimpleValue(Object container, QName name, BinaryTypeDefinition type) {
val Object value = container.getValue(name, Object); //Constants.BYTES_CLASS);
if(value === null) return null;
return new SimpleNodeTOImpl(name, null, value);
}
- private def <T> T getValue(Object object, QName node, Class<T> type) {
+ public static def <T> T getValue(Object object, QName node, Class<T> type) {
val methodName = BindingGeneratorImpl.getterMethodName(node.localName, Types.typeForClass(type));
var clz = object.class;
if (object instanceof DataContainer) {
return value.getEncapsulatedValue(type);
}
- private def <T> T getEncapsulatedValue(Object value, Class<T> type) {
+ public static def <T> T getEncapsulatedValue(Object value, Class<T> type) {
val method = value.class.getMethod("getValue");
if (method !== null && type.isAssignableFrom(method.returnType)) {
return method.invoke(value) as T;
return buildMethod.invoke(builder) as DataObject;
}
- def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+ private def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
ListSchemaNode schema) {
if (schema.keyDefinition !== null && !schema.keyDefinition.empty) {
val value = node.keyToBindingKey(loader, type, schema);
builder.setProperty("key", value);
}
+ node.fillBuilderFromContainer(builder,loader,type,schema);
}
+
+
- def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+ private def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
ContainerSchemaNode schema) {
+ node.fillBuilderFromContainer(builder,loader,type,schema);
}
- def Object keyToBindingKey(CompositeNode node, ClassLoader loader, GeneratedType type, ListSchemaNode schema) {
+ private def void fillBuilderFromContainer(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type, DataNodeContainer schema) {
+ val Multimap<QName,Node<?>> dataMap = ArrayListMultimap.create();
+ for(child :node.children) {
+ dataMap.put(child.nodeType,node);
+ }
+ for(entry : dataMap.asMap.entrySet) {
+ val entrySchema = schema.getDataChildByName(entry.key);
+ val entryType = type.methodDefinitions.byQName(entry.key);
+ entry.value.addValueToBuilder(builder,loader,entryType,entrySchema);
+ }
+ }
+
+ private def Type byQName(List<MethodSignature> signatures, QName name) {
+
+ }
+
+ private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, LeafSchemaNode container) {
+
+ }
+
+
+
+ private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, ContainerSchemaNode container) {
+
+ }
+
+
+ private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, ListSchemaNode container) {
+
+ }
+
+ private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, LeafListSchemaNode container) {
+
+ }
+
+
+
+
+ private def Object keyToBindingKey(CompositeNode node, ClassLoader loader, GeneratedType type, ListSchemaNode schema) {
val keyClass = loader.loadClass(type.keyFQN);
val constructor = keyClass.constructors.get(0);
val keyType = type.keyTypeProperties;
return ClassLoaderUtils.construct(constructor, args);
}
- def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ private def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
LeafSchemaNode node2) {
deserializeSimpleValueImpl(node, loader, type, node2.type);
}
- def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ private def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
LeafListSchemaNode node2) {
deserializeSimpleValueImpl(node, loader, type, node2.type);
}
- def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ private def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
ExtendedType definition) {
deserializeSimpleValueImpl(node, loader, type, definition.baseType);
}
- def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ private def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
StringTypeDefinition definition) {
if (type instanceof GeneratedTransferObject) {
val cls = loader.getClassForType(type);
return node.value;
}
- def Class<?> getClassForType(ClassLoader loader, Type type) {
+ private def Class<?> getClassForType(ClassLoader loader, Type type) {
loader.loadClass(type.fullyQualifiedName);
}
- def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ private def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
TypeDefinition definition) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
- def Map<String, GeneratedProperty> getKeyTypeProperties(GeneratedType type) {
+ private def Map<String, GeneratedProperty> getKeyTypeProperties(GeneratedType type) {
val method = FluentIterable.from(type.methodDefinitions).findFirst[name == "getKey"]
val key = method.returnType as GeneratedTransferObject;
val ret = new HashMap<String, GeneratedProperty>();
return ret;
}
- def void setProperty(Object object, String property, Object value) {
+ private def void setProperty(Object object, String property, Object value) {
val cls = object.class;
val valMethod = cls.getMethod("set" + property.toFirstUpper, value.class);
if (valMethod != null)
valMethod.invoke(object, value);
}
- def String getBuilderFQN(Type type) '''«type.fullyQualifiedName»Builder'''
+ private def String getBuilderFQN(Type type) '''«type.fullyQualifiedName»Builder'''
- def String getKeyFQN(Type type) '''«type.fullyQualifiedName»Key'''
+ private def String getKeyFQN(Type type) '''«type.fullyQualifiedName»Key'''
}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class CompositeNodeUtils {
+
+}
import java.util.Collection;
import java.util.Collections;
+import javassist.ClassPool;
+
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.dom.serializer.impl.TransformerGenerator;
import org.opendaylight.controller.sal.core.api.Broker;
import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
@Override
public void onSessionInitiated(ProviderSession session) {
- MappingServiceImpl mappingImpl = new MappingServiceImpl();
- mappingImpl.setSchemaService(session.getService(SchemaService.class));
+ RuntimeGeneratedMappingServiceImpl mappingImpl = new RuntimeGeneratedMappingServiceImpl();
+ SchemaService schemaService = (session.getService(SchemaService.class));
+ ClassPool pool = new ClassPool();
+ mappingImpl.setBinding(new TransformerGenerator(pool));
mappingImpl.start();
-
+ schemaService.registerSchemaServiceListener(mappingImpl);
mappingService = mappingImpl;
dataConnector = new BindingIndependentDataServiceConnector();
dataConnector.setBaDataService(baDataService);
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.controller.sal.binding.dom.serializer.impl.TransformerGenerator
+import javassist.ClassPool
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import java.util.Map
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import java.util.HashMap
+import java.util.concurrent.ConcurrentHashMap
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import java.util.Map.Entry
+import java.util.AbstractMap.SimpleEntry
+import org.opendaylight.yangtools.yang.model.api.SchemaPath
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.binding.generator.util.Types
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
+import org.opendaylight.yangtools.yang.binding.DataContainer
+import static com.google.common.base.Preconditions.*;
+import java.util.List
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.concepts.Delegator
+import java.util.concurrent.ConcurrentMap
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import org.opendaylight.yangtools.yang.binding.BindingCodec
+
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener {
+
+ ClassPool pool;
+
+ @Property
+ extension TransformerGenerator binding;
+
+ val ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap();
+
+ val ConcurrentMap<Class<? extends DataContainer>, TransformerWrapper> domSerializers = new ConcurrentHashMap();
+
+ @Property
+ val ConcurrentMap<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
+
+ @Property
+ val ConcurrentMap<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
+
+ override onGlobalContextUpdated(SchemaContext arg0) {
+ recreateBindingContext(arg0);
+ }
+
+ def recreateBindingContext(SchemaContext schemaContext) {
+ val newBinding = new BindingGeneratorImpl();
+ newBinding.generateTypes(schemaContext);
+
+ for (entry : newBinding.moduleContexts.entrySet) {
+
+ //val module = entry.key;
+ val context = entry.value;
+ updateBindingFor(context.childNodes, schemaContext);
+
+ val typedefs = context.typedefs;
+ for(typedef : typedefs.values) {
+ binding.typeDefinitions.put(typedef,typedef as GeneratedType);
+ }
+ }
+ }
+
+ override CompositeNode toDataDom(DataObject data) {
+ toCompositeNodeImpl(data);
+ }
+
+ override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+ Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+ val key = toDataDomImpl(entry.key);
+ val data = toCompositeNodeImpl(entry.value);
+ return new SimpleEntry(key, data);
+ }
+
+ private def CompositeNode toCompositeNodeImpl(DataObject object) {
+ val cls = object.implementedInterface;
+ val transformator = resolveTransformator(cls);
+ val ret = transformator.transform(object);
+ return ret;
+ }
+
+ private def resolveTransformator(Class<? extends DataContainer> cls) {
+ val serializer = domSerializers.get(cls);
+ if (serializer !== null) {
+ return serializer;
+ }
+ val transformerClass = binding.transformerFor(cls).newInstance;
+ val wrapper = new TransformerWrapper(transformerClass);
+ domSerializers.putIfAbsent(cls, wrapper);
+ return wrapper;
+ }
+
+ private def org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDomImpl(
+ InstanceIdentifier<? extends DataObject> object) {
+ val pathArguments = object.path;
+ var Class<? extends DataObject> parent;
+ val dataDomArgs = new ArrayList<PathArgument>();
+ for (pathArgument : pathArguments) {
+ dataDomArgs.add(pathArgument.toDataDomPathArgument(parent));
+ parent = pathArgument.type;
+ }
+
+ return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(dataDomArgs);
+ }
+
+ override org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+ InstanceIdentifier<? extends DataObject> path) {
+ return toDataDomImpl(path);
+ }
+
+ override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result) {
+ return dataObjectFromDataDomImpl(path, result);
+ }
+
+ def DataObject dataObjectFromDataDomImpl(InstanceIdentifier<? extends DataObject> identifier, CompositeNode node) {
+ val targetType = identifier.targetType
+ val transformer = resolveTransformator(targetType);
+ val ret = transformer.deserialize(node) as DataObject;
+ return ret;
+ }
+
+ def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
+ for (entry : map.entrySet) {
+ val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+ typeToDefinition.put(entry.value, entry.value);
+ typeToSchemaNode.put(entry.value, schemaNode)
+ }
+ }
+
+ private def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument,
+ Class<? extends DataObject> parent) {
+ val Class<?> rawType = argument.type;
+ val ref = Types.typeForClass(rawType);
+ val schemaType = typeToSchemaNode.get(ref);
+ val qname = schemaType.QName
+
+ val Object key = argument.key;
+ val predicates = key.toPredicates(schemaType as ListSchemaNode);
+
+ return new NodeIdentifierWithPredicates(qname, predicates);
+ }
+
+ private def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
+ val keyDefinitions = node.keyDefinition;
+ val map = new HashMap<QName, Object>();
+ for (keydef : keyDefinitions) {
+ val keyNode = node.getDataChildByName(keydef) as LeafSchemaNode;
+ val value = BindingMapping.getSimpleValue(identifier, keydef, keyNode.type);
+ map.put(keydef, value.value);
+ }
+ return map;
+ }
+
+ private def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
+ val ref = Types.typeForClass(argument.type);
+ val qname = typeToSchemaNode.get(ref).QName
+ return new NodeIdentifier(qname);
+ }
+
+ public def void start() {
+ pool = new ClassPool()
+ binding = new TransformerGenerator(pool);
+
+ binding.typeToDefinition = typeToDefinition
+ binding.typeToSchemaNode = typeToSchemaNode
+ binding.typeDefinitions = typeDefinitions
+
+ }
+}
+
+class TransformerWrapper implements // //
+Delegator<BindingCodec<Map<QName, Object>, Object>> {
+
+ @Property
+ val BindingCodec<Map<QName, Object>, Object> delegate;
+
+ new(BindingCodec<Map<QName, Object>, Object> delegate) {
+ _delegate = delegate;
+ }
+
+ def CompositeNode transform(DataObject input) {
+ val ret = delegate.serialize(input);
+ val node = toNode(ret)
+ return node as CompositeNode;
+ }
+
+ def deserialize(CompositeNode node) {
+ if (node === null) {
+ return null;
+ }
+ val Map mapCapture = node
+ return delegate.deserialize(mapCapture as Map<QName,Object>);
+ }
+
+ static def Node<?> toNode(Map map) {
+ val nodeMap = map as Map<QName,Object>;
+ checkArgument(map.size == 1);
+ val elem = nodeMap.entrySet.iterator.next;
+ val qname = elem.key;
+ val value = elem.value;
+ toNodeImpl(qname, value);
+ }
+
+ static def dispatch Node<?> toNodeImpl(QName name, List objects) {
+ val values = new ArrayList<Node<?>>(objects.size);
+ for (obj : objects) {
+ values.add(toNode(obj as Map));
+ }
+ return new CompositeNodeTOImpl(name, null, values);
+ }
+
+ static def dispatch Node<?> toNodeImpl(QName name, Map<QName, Object> object) {
+ throw new UnsupportedOperationException("Unsupported node hierarchy.");
+ }
+
+ static def dispatch Node<?> toNodeImpl(QName name, Object object) {
+ return new SimpleNodeTOImpl(name, null, object);
+ }
+}
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-
public class ClassLoaderUtils {
public static <V> V withClassLoader(ClassLoader cls,Callable<V> function) throws Exception {
Object[] initargs = objects.toArray(new Object[]{});
return constructor.newInstance(initargs);
}
+
+
+ public static Class<?> loadClassWithTCCL(String name) throws ClassNotFoundException {
+ return Thread.currentThread().getContextClassLoader().loadClass(name);
+ }
}
\ No newline at end of file
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.RuntimeGeneratedMappingServiceImpl;
import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
DataBrokerService biDataService;
DataProviderService baDataService;
- private MappingServiceImpl mappingServiceImpl;
- private MappingServiceImpl mappingService;
+ private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
+ private BindingIndependentMappingService mappingService;
private DataBrokerImpl baDataImpl;
private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
private ListeningExecutorService executor;
biDataImpl.registerOperationalReader(treeRoot, dataStore);
biDataImpl.registerCommitHandler(treeRoot, dataStore);
- mappingServiceImpl = new MappingServiceImpl();
+ mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
mappingService = mappingServiceImpl;
-
+ mappingServiceImpl.start();
connectorServiceImpl = new BindingIndependentDataServiceConnector();
connectorServiceImpl.setBaDataService(baDataService);
String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
"node-inventory.yang" };
- mappingService.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
+ mappingServiceImpl.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
+
}
@Test
public void simpleModifyOperation() throws Exception {
- DataModificationTransaction transaction = baDataService.beginTransaction();
- assertNotNull(transaction);
NodeRef node1 = createNodeRef("0");
DataObject node = baDataService.readConfigurationData(node1.getValue());
assertNull(node);
Node nodeData1 = createNode("0");
+
+ DataModificationTransaction transaction = baDataService.beginTransaction();
transaction.putConfigurationData(node1.getValue(), nodeData1);
Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
assertNotNull(commitResult);
assertEquals(nodeData1.getKey(), readedData.getKey());
- DataModificationTransaction transaction2 = baDataService.beginTransaction();
+ NodeRef nodeFoo = createNodeRef("foo");
+ NodeRef nodeBar = createNodeRef("bar");
+ Node nodeFooData = createNode("foo");
+ Node nodeBarData = createNode("bar");
+
+
+ DataModificationTransaction insertMoreTr = baDataService.beginTransaction();
+ insertMoreTr.putConfigurationData(nodeFoo.getValue(), nodeFooData);
+ insertMoreTr.putConfigurationData(nodeBar.getValue(), nodeBarData);
+ RpcResult<TransactionStatus> result2 = insertMoreTr.commit().get();
+
+ assertNotNull(result2);
+ assertNotNull(result2.getResult());
+ assertEquals(TransactionStatus.COMMITED, result.getResult());
+
+ Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder().node(Nodes.class).toInstance());
+ assertNotNull(allNodes);
+ assertNotNull(allNodes.getNode());
+ assertEquals(3, allNodes.getNode().size());
+
+
+ /**
+ * We create transaction no 2
+ *
+ */
+ DataModificationTransaction removalTransaction = baDataService.beginTransaction();
assertNotNull(transaction);
- transaction2.removeConfigurationData(node1.getValue());
+ /**
+ * We remove node 1
+ *
+ */
+ removalTransaction.removeConfigurationData(node1.getValue());
- Future<RpcResult<TransactionStatus>> commitResult2 = transaction2.commit();
+ /**
+ * We commit transaction
+ */
+ Future<RpcResult<TransactionStatus>> commitResult2 = removalTransaction.commit();
assertNotNull(commitResult2);
- RpcResult<TransactionStatus> result2 = commitResult2.get();
+ RpcResult<TransactionStatus> result3 = commitResult2.get();
- assertNotNull(result2);
- assertNotNull(result2.getResult());
+ assertNotNull(result3);
+ assertNotNull(result3.getResult());
assertEquals(TransactionStatus.COMMITED, result2.getResult());
DataObject readedData2 = baDataService.readConfigurationData(node1.getValue());