package net.floodlightcontroller.devicemanager.internal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.EnumSet; import java.util.List; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.IPv4Address; import org.projectfloodlight.openflow.types.IPv6Address; import org.projectfloodlight.openflow.types.MacAddress; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.VlanVid; import net.floodlightcontroller.devicemanager.SwitchPort; import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField; import com.fasterxml.jackson.annotation.JsonProperty; public class DeviceSyncRepresentation { public static class SyncEntity implements Comparable<SyncEntity> { @JsonProperty public long macAddress; @JsonProperty public int ipv4Address; // TODO Sync IPv6 address @JsonProperty public short vlan; @JsonProperty public long switchDPID; @JsonProperty public int switchPort; @JsonProperty public Date lastSeenTimestamp; @JsonProperty public Date activeSince; public SyncEntity() { // do nothing; } public SyncEntity(Entity e) { this.macAddress = (e.getMacAddress() != null ? e.getMacAddress().getLong() : 0); this.ipv4Address = (e.getIpv4Address() != null ? e.getIpv4Address().getInt() : 0); this.vlan = (e.getVlan() != null ? e.getVlan().getVlan() : -1); this.switchDPID = (e.getSwitchDPID() != null ? e.getSwitchDPID().getLong() : 0); this.switchPort = (e.getSwitchPort() != null ? e.getSwitchPort().getPortNumber() : 0); if (e.getLastSeenTimestamp() == null) this.lastSeenTimestamp = null; else this.lastSeenTimestamp = new Date(e.getLastSeenTimestamp().getTime()); if (e.getActiveSince() == null) this.activeSince = null; else this.activeSince = new Date(e.getActiveSince().getTime()); } public Entity asEntity() { Entity e = new Entity(MacAddress.of(macAddress), VlanVid.ofVlan(vlan), IPv4Address.of(ipv4Address), IPv6Address.NONE, DatapathId.of(switchDPID), OFPort.of(switchPort), lastSeenTimestamp); e.setActiveSince(activeSince); return e; } @Override public int compareTo(SyncEntity other) { return lastSeenTimestamp.compareTo(other.lastSeenTimestamp); } @Override public String toString() { return asEntity().toString(); } } private String key; private List<SyncEntity> entities; public DeviceSyncRepresentation() { // do nothing } public DeviceSyncRepresentation(Device device) { this.key = computeKey(device); this.entities = new ArrayList<SyncEntity>(); // FIXME: do we need the APs with errors as well?? // FIXME SwitchPort[] aps = device.getAttachmentPoints(); for (Entity e : device.getEntities()) { // Add the entities from the device only if they either don't // have a switch/port or if they are an attachment point or // if they have an IP address. if (!e.hasSwitchPort()) { this.entities.add(new SyncEntity(e)); } else if (isAttachmentPointEntity(aps, e)) { this.entities.add(new SyncEntity(e)); } else if (!e.getIpv4Address().equals(IPv4Address.NONE)) { this.entities.add(new SyncEntity(e)); } } Collections.sort(this.entities); } private static boolean isAttachmentPointEntity(SwitchPort[] aps, Entity e) { if (!e.hasSwitchPort()) return false; for (SwitchPort p : aps) { if (e.getSwitchDPID().equals(p.getNodeId()) && e.getSwitchPort().equals(p.getPortId()) && (!e.getSwitchDPID().equals(DatapathId.NONE) || !e.getSwitchPort().equals(OFPort.ZERO))) { return true; } } return false; } static String computeKey(Device d) { StringBuilder bld = new StringBuilder(d.getEntityClass().getName()); bld.append("::"); EnumSet<DeviceField> keyFields = d.getEntityClass().getKeyFields(); if (keyFields.contains(DeviceField.MAC)) { bld.append(d.getMACAddressString()); bld.append("::"); } if (keyFields.contains(DeviceField.VLAN)) { if (d.getVlanId() != null) bld.append(Arrays.toString(d.getVlanId())); bld.append("::"); } if (keyFields.contains(DeviceField.SWITCH) || keyFields.contains(DeviceField.PORT) ) { if (d.getAttachmentPoints(true) != null) bld.append(Arrays.toString(d.getAttachmentPoints(true))); bld.append("::"); } if (keyFields.contains(DeviceField.IPv4)) { if (d.getIPv4Addresses() != null) bld.append(Arrays.toString(d.getIPv4Addresses())); bld.append("::"); } if (keyFields.contains(DeviceField.IPv6)) { if (d.getIPv6Addresses() != null) bld.append(Arrays.toString(d.getIPv6Addresses())); bld.append("::"); } return bld.toString(); } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public List<SyncEntity> getEntities() { return entities; } public void setEntities(List<SyncEntity> entities) { if (entities == null) { this.entities = null; } else { List<SyncEntity> tmp = new ArrayList<SyncEntity>(entities); Collections.sort(tmp); this.entities = tmp; } } @Override public String toString() { return key; } }