package org.ovirt.engine.api.restapi.resource; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.ovirt.engine.api.common.util.DetailHelper; import org.ovirt.engine.api.common.util.LinkHelper; import org.ovirt.engine.api.model.Bonding; import org.ovirt.engine.api.model.Host; import org.ovirt.engine.api.model.HostNIC; import org.ovirt.engine.api.model.HostNics; import org.ovirt.engine.api.model.Link; import org.ovirt.engine.api.model.Network; import org.ovirt.engine.api.model.Slaves; import org.ovirt.engine.api.model.Statistic; import org.ovirt.engine.api.model.Statistics; import org.ovirt.engine.api.resource.HostNicResource; import org.ovirt.engine.api.resource.HostNicsResource; import org.ovirt.engine.core.common.action.AddBondParameters; import org.ovirt.engine.core.common.action.RemoveBondParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VdsNetworkInterface; import org.ovirt.engine.core.common.businessentities.network; import org.ovirt.engine.core.common.queries.GetAllNetworkQueryParamenters; import org.ovirt.engine.core.common.queries.GetVdsByVdsIdParameters; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.common.queries.VdsGroupQueryParamenters; import org.ovirt.engine.core.compat.Guid; public class BackendHostNicsResource extends AbstractBackendCollectionResource<HostNIC, VdsNetworkInterface> implements HostNicsResource { static final String SUB_COLLECTIONS = "statistics"; private String hostId; public BackendHostNicsResource(String hostId) { super(HostNIC.class, VdsNetworkInterface.class, SUB_COLLECTIONS); this.hostId = hostId; } public String getHostId() { return hostId; } public HostNics list() { HostNics ret = new HostNics(); List<VdsNetworkInterface> ifaces = getCollection(); List<network> clusterNetworks = getClusterNetworks(); Map<String, String> networkIds = new HashMap<String, String>(); for(network nwk : clusterNetworks) { networkIds.put(nwk.getname(), nwk.getId().toString()); } for (VdsNetworkInterface iface : ifaces) { HostNIC hostNic = populate(map(iface, ifaces), iface); if (networkIds.containsKey(iface.getNetworkName())) { hostNic.getNetwork().setId(networkIds.get(iface.getNetworkName())); hostNic.getNetwork().setName(null); } ret.getHostNics().add(addLinks(hostNic)); } return ret; } @SuppressWarnings("serial") @Override public Response add(final HostNIC nic) { validateParameters(nic, "name", "network.id|name", "bonding.slaves.id|name"); return performCreation(VdcActionType.AddBond, new AddBondParameters(asGuid(hostId), nic.getName(), lookupNetwork(nic.getNetwork()), lookupSlaves(nic)){{setBondingOptions(map(nic, null).getBondOptions());}}, new HostNicResolver(nic.getName())); } @Override public Response performRemove(String id) { return performAction(VdcActionType.RemoveBond, new RemoveBondParameters(asGuid(hostId), lookupInterface(id).getName())); } @Override @SingleEntityResource public HostNicResource getHostNicSubResource(String id) { return inject(new BackendHostNicResource(id, this)); } public HostNIC lookupNic(String id) { List<VdsNetworkInterface> ifaces = getCollection(); for (VdsNetworkInterface iface : ifaces) { if (iface.getId().toString().equals(id)) { HostNIC hostNic = populate(map(iface, ifaces), iface); for(network nwk : getClusterNetworks()){ if(nwk.getname().equals(iface.getNetworkName())) { hostNic.getNetwork().setId(nwk.getId().toString()); hostNic.getNetwork().setName(null); break; } } return addLinks(hostNic); } } return notFound(); } public VdsNetworkInterface lookupInterface(String id) { for (VdsNetworkInterface iface : getCollection()) { if (iface.getId().toString().equals(id)) { return iface; } } return entityNotFound(); } protected VdsNetworkInterface lookupInterfaceByName(String name) { for (VdsNetworkInterface iface : getCollection()) { if (iface.getName().equals(name)) { return iface; } } return null; } protected List<VdsNetworkInterface> getCollection() { return getBackendCollection(VdcQueryType.GetVdsInterfacesByVdsId, new GetVdsByVdsIdParameters(asGuid(hostId))); } protected List<VdsNetworkInterface> getCollection(List<VdsNetworkInterface> collection) { if (collection != null) { return collection; } else { return getCollection(); } } @Override public HostNIC addParents(HostNIC nic) { nic.setHost(new Host()); nic.getHost().setId(hostId); return nic; } protected HostNIC map(VdsNetworkInterface iface, List<VdsNetworkInterface> ifaces) { return map(iface, null, ifaces); } protected HostNIC map(VdsNetworkInterface iface, HostNIC template, List<VdsNetworkInterface> ifaces) { HostNIC nic = super.map(iface, template); if (iface.getBonded() != null && iface.getBonded()) { nic = addSlaveLinks(nic, getCollection(ifaces)); } else if (iface.getBondName() != null) { nic = addMasterLink(nic, iface.getBondName(), getCollection(ifaces)); } return nic; } @Override protected HostNIC map(VdsNetworkInterface entity, HostNIC template) { return map(entity, template, null); } @Override protected VdsNetworkInterface map(HostNIC entity, VdsNetworkInterface template) { return super.map(entity, template); } protected HostNIC addSlaveLinks(HostNIC nic, List<VdsNetworkInterface> ifaces) { if(nic.getBonding() == null) nic.setBonding(new Bonding()); nic.getBonding().setSlaves(new Slaves()); for (VdsNetworkInterface i : ifaces) { if (isSlave(i, nic.getName())) { nic.getBonding().getSlaves().getSlaves().add(slave(i.getId().toString())); } } return nic; } protected boolean isSlave(VdsNetworkInterface iface, String masterName) { return iface.getBondName() != null && iface.getBondName().equals(masterName); } protected HostNIC slave(String id) { HostNIC slave = new HostNIC(); slave.setId(id); slave.setHost(new Host()); slave.getHost().setId(hostId); slave = LinkHelper.addLinks(getUriInfo(), slave); slave.setHost(null); return slave; } protected HostNIC addMasterLink(HostNIC nic, String bondName, List<VdsNetworkInterface> ifaces) { for (VdsNetworkInterface i : ifaces) { if (i.getName().equals(bondName)) { nic.getLinks().add(masterLink(i.getId().toString())); break; } } return nic; } protected Link masterLink(String id) { Link master = new Link(); master.setRel("master"); master.setHref(idToHref(id)); return master; } protected String idToHref(String id) { HostNIC master = new HostNIC(); master.setId(id); master.setHost(new Host()); master.getHost().setId(hostId); return LinkHelper.addLinks(getUriInfo(), master).getHref(); } protected network lookupNetwork(Network network) { String id = network.getId(); String name = network.getName(); for (network entity : getBackendCollection(network.class, VdcQueryType.GetAllNetworks, new GetAllNetworkQueryParamenters(Guid.Empty))) { if ((id != null && id.equals(entity.getId().toString())) || (name != null && name.equals(entity.getname()))) { return entity; } } return handleError(new EntityNotFoundException(id != null ? id : name), false); } protected String[] lookupSlaves(HostNIC nic) { List<String> slaves = new ArrayList<String>(); for (HostNIC slave : nic.getBonding().getSlaves().getSlaves()) { if (slave.isSetId()) { for (VdsNetworkInterface iface : getCollection()) { if (iface.getId().toString().equals(slave.getId())) { slaves.add(iface.getName()); } } } else { slaves.add(slave.getName()); } } return slaves.toArray(new String[slaves.size()]); } @Override protected HostNIC populate(HostNIC model, VdsNetworkInterface entity) { return addStatistics(model, entity, uriInfo, httpHeaders); } HostNIC addStatistics(HostNIC model, VdsNetworkInterface entity, UriInfo ui, HttpHeaders httpHeaders) { if (DetailHelper.include(httpHeaders, "statistics")) { model.setStatistics(new Statistics()); HostNicStatisticalQuery query = new HostNicStatisticalQuery(newModel(model.getId())); List<Statistic> statistics = query.getStatistics(entity); for (Statistic statistic : statistics) { LinkHelper.addLinks(ui, statistic, query.getParentType()); } model.getStatistics().getStatistics().addAll(statistics); } return model; } protected class HostNicResolver extends EntityIdResolver { private String name; HostNicResolver(String name) { this.name = name; } @Override public VdsNetworkInterface lookupEntity(Guid id) { assert(id == null); // AddBond returns nothing, lookup name instead return lookupInterfaceByName(name); } } @SuppressWarnings("unchecked") protected List<network> getClusterNetworks(){ VDS vds = getEntity(VDS.class, VdcQueryType.GetVdsByVdsId, new GetVdsByVdsIdParameters(Guid.createGuidFromString(getHostId())), "Host"); return getEntity(List.class, VdcQueryType.GetAllNetworksByClusterId, new VdsGroupQueryParamenters(vds.getvds_group_id()), "Networks"); } public network lookupClusterNetwork(Network net) { List<network> networks = getClusterNetworks(); if(net.isSetId()){ for(network nwk : networks){ if (nwk.getId().toString().equals(net.getId())) return nwk; } }else{ String networkName = net.getName(); for(network nwk : networks){ if(nwk.getname().equals(networkName)) return nwk; } } return notFound(network.class); } }