/*
* Copyright (c) 2016 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.groupbasedpolicy.base_endpoint;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.EndpointUtils;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpointBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegKey;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
public class RegisterEndpointInputVerificator {
private static final Logger LOG = LoggerFactory.getLogger(RegisterEndpointInputVerificator.class);
public static ListenableFuture<RpcResult<Void>> verifyRegisterEndpointInput(RegisterEndpointInput input,
ReadTransaction rTx) {
ListenableFuture<RpcResult<Void>> result;
List<AddressEndpointReg> addressEndpointRegs = nullToEmpty(input.getAddressEndpointReg());
List<ContainmentEndpointReg> containmentEndpointRegs = nullToEmpty(input.getContainmentEndpointReg());
for (AddressEndpointReg addressEndpointReg : addressEndpointRegs) {
result = verifyAddressEndpointChilds(addressEndpointRegs, addressEndpointReg, rTx);
if (result != null) {
return result;
}
result = verifyAddressEndpointParents(addressEndpointRegs, containmentEndpointRegs, addressEndpointReg,
rTx);
if (result != null) {
return result;
}
}
result = verifyContainmentEndpointChilds(addressEndpointRegs, containmentEndpointRegs, rTx);
if (result != null) {
return result;
}
return null;
}
private static ListenableFuture<RpcResult<Void>> verifyAddressEndpointChilds(
List<AddressEndpointReg> addressEndpointRegs, AddressEndpointReg addressEndpointReg, ReadTransaction rTx) {
for (ChildEndpoint childEndpoint : nullToEmpty(addressEndpointReg.getChildEndpoint())) {
AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
if (addressEndpointRegChild == null) {
Optional<AddressEndpoint> addressEndpointOptional =
DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
key.getAddressType(), key.getContextId(), key.getContextType())),
rTx);
if (!addressEndpointOptional.isPresent()) {
LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint.getKey());
return buildFailFeature(String.format("Child AddressEndpoint %s does not exist in RPC and DS.",
childEndpoint.getKey()));
}
} else {
ParentEndpointChoice parentEndpointChoice = addressEndpointRegChild.getParentEndpointChoice();
List<ParentEndpoint> parentEndpoints = EndpointUtils.getParentEndpoints(parentEndpointChoice);
if (!parentEndpoints.contains(new ParentEndpointBuilder(addressEndpointReg).build())) {
LOG.debug("Child AddressEndpoint {} does not contain a parent AddressEndpoint {}.\nChild: {}",
addressEndpointRegChild.getKey(), addressEndpointReg.getKey(), addressEndpointRegChild);
return buildFailFeature(String.format(
"Child AddressEndpoint does not contain a parent AddressEndpoint."
+ "\nChild AddressEndpoint: %s" + "\nParent AddressEndpoint: %s",
addressEndpointRegChild.getKey(), addressEndpointReg.getKey()));
}
}
}
return null;
}
private static ListenableFuture<RpcResult<Void>> verifyAddressEndpointParents(
List<AddressEndpointReg> addressEndpointRegs, List<ContainmentEndpointReg> containmentEndpointRegs,
AddressEndpointReg addressEndpointReg, ReadTransaction rTx) {
ParentEndpointChoice parentEndpointChoice = addressEndpointReg.getParentEndpointChoice();
for (ParentEndpoint parentEndpoint : EndpointUtils.getParentEndpoints(parentEndpointChoice)) {
AddressEndpointRegKey key = new AddressEndpointRegKey(parentEndpoint.getAddress(),
parentEndpoint.getAddressType(), parentEndpoint.getContextId(), parentEndpoint.getContextType());
AddressEndpointReg addressEndpointRegParent = findAddressEndpointReg(key, addressEndpointRegs);
if (addressEndpointRegParent == null) {
Optional<AddressEndpoint> addressEndpointOptional =
DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
key.getAddressType(), key.getContextId(), key.getContextType())),
rTx);
if (!addressEndpointOptional.isPresent()) {
LOG.debug("Parent AddressEndpoint {} does not exist in RPC and DS.", parentEndpoint.getKey());
return buildFailFeature(String.format("Parent AddressEndpoint %s does not exist in RPC and DS.",
parentEndpoint.getKey()));
}
} else {
List<ChildEndpoint> childEndpoints = addressEndpointRegParent.getChildEndpoint();
if (!nullToEmpty(childEndpoints).contains(new ChildEndpointBuilder(addressEndpointReg).build())) {
LOG.debug("Parent AddressEndpoint {} does not contain a child AddressEndpoint {}.\nParent: {}",
addressEndpointRegParent.getKey(), addressEndpointReg.getKey(), addressEndpointRegParent);
return buildFailFeature(String.format(
"Parent AddressEndpoint does not contain a child AddressEndpoint."
+ "\nParent AddressEndpoint: %s" + "\nChild AddressEndpoint: %s",
addressEndpointRegParent.getKey(), addressEndpointReg.getKey()));
}
}
}
for (ParentContainmentEndpoint parentEndpoint : EndpointUtils
.getParentContainmentEndpoints(parentEndpointChoice)) {
ContainmentEndpointRegKey key =
new ContainmentEndpointRegKey(parentEndpoint.getContextId(), parentEndpoint.getContextType());
ContainmentEndpointReg containmentEndpointRegParent =
findContainmentEndpointReg(key, containmentEndpointRegs);
if (containmentEndpointRegParent == null) {
Optional<ContainmentEndpoint> containmentEndpointOptional =
DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.containmentEndpointIid(
new ContainmentEndpointKey(key.getContextId(), key.getContextType())), rTx);
if (!containmentEndpointOptional.isPresent()) {
LOG.debug("Parent ContainmentEndpoint {} does not exist in RPC and DS.", parentEndpoint.getKey());
return buildFailFeature(String.format("Parent ContainmentEndpoint %s does not exist in RPC and DS.",
parentEndpoint.getKey()));
}
} else {
List<ChildEndpoint> childEndpoints = containmentEndpointRegParent.getChildEndpoint();
if (!nullToEmpty(childEndpoints).contains(new ChildEndpointBuilder(addressEndpointReg).build())) {
LOG.debug("Parent ContainmentEndpoint {} does not contain a child AddressEndpoint {}.\nParent: {}",
containmentEndpointRegParent.getKey(), addressEndpointReg.getKey(),
containmentEndpointRegParent);
return buildFailFeature(String.format(
"Parent ContainmentEndpoint does not contain a child AddressEndpoint."
+ "\nParent ContainmentEndpoint: %s" + "\nChild AddressEndpoint: %s",
containmentEndpointRegParent.getKey(), addressEndpointReg.getKey()));
}
}
}
return null;
}
private static ListenableFuture<RpcResult<Void>> verifyContainmentEndpointChilds(
List<AddressEndpointReg> addressEndpointRegs, List<ContainmentEndpointReg> containmentEndpointRegs,
ReadTransaction rTx) {
for (ContainmentEndpointReg containmentEndpointReg : nullToEmpty(containmentEndpointRegs)) {
for (ChildEndpoint childEndpoint : nullToEmpty(containmentEndpointReg.getChildEndpoint())) {
AddressEndpointRegKey key = new AddressEndpointRegKey(childEndpoint.getAddress(),
childEndpoint.getAddressType(), childEndpoint.getContextId(), childEndpoint.getContextType());
AddressEndpointReg addressEndpointRegChild = findAddressEndpointReg(key, addressEndpointRegs);
if (addressEndpointRegChild == null) {
Optional<AddressEndpoint> addressEndpointOptional =
DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
IidFactory.addressEndpointIid(new AddressEndpointKey(key.getAddress(),
key.getAddressType(), key.getContextId(), key.getContextType())),
rTx);
if (!addressEndpointOptional.isPresent()) {
LOG.debug("Child AddressEndpoint {} does not exist in RPC and DS.", childEndpoint.getKey());
return buildFailFeature(String.format("Child AddressEndpoint %s does not exist in RPC and DS.",
childEndpoint.getKey()));
}
} else {
List<ParentContainmentEndpoint> parentContainmentEndpoints = EndpointUtils
.getParentContainmentEndpoints(addressEndpointRegChild.getParentEndpointChoice());
if (!parentContainmentEndpoints
.contains(new ParentContainmentEndpointBuilder(containmentEndpointReg).build())) {
LOG.debug(
"Child AddressEndpoint {} does not contain a parent ContainmentEndpoint {}.\nChild: {}",
addressEndpointRegChild.getKey(), containmentEndpointReg.getKey(),
addressEndpointRegChild);
return buildFailFeature(String.format(
"Child AddressEndpoint does not contain a parent ContainmentEndpoint."
+ "\nChild AddressEndpoint: %s" + "\nParent ContainmentEndpoint: %s",
addressEndpointRegChild.getKey(), containmentEndpointReg.getKey()));
}
}
}
}
return null;
}
private static AddressEndpointReg findAddressEndpointReg(AddressEndpointRegKey key,
List<AddressEndpointReg> addressEndpointRegs) {
for (AddressEndpointReg addressEndpointReg : addressEndpointRegs) {
if (addressEndpointReg.getKey().equals(key)) {
return addressEndpointReg;
}
}
return null;
}
private static ContainmentEndpointReg findContainmentEndpointReg(ContainmentEndpointRegKey key,
List<ContainmentEndpointReg> addressEndpointRegs) {
for (ContainmentEndpointReg containmentEndpointReg : addressEndpointRegs) {
if (containmentEndpointReg.getKey().equals(key)) {
return containmentEndpointReg;
}
}
return null;
}
private static ListenableFuture<RpcResult<Void>> buildFailFeature(String message) {
return Futures
.immediateFuture(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.PROTOCOL, message).build());
}
private static <T> List<T> nullToEmpty(@Nullable List<T> list) {
return list == null ? Collections.emptyList() : list;
}
}