From: Michael Vorburger Date: Wed, 6 Jun 2018 16:22:59 +0000 (+0200) Subject: propagate datastore exceptions all the way to northbound X-Git-Tag: release/fluorine~13 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=59a7c333e9d7f110d46beca779a2735710504319;p=neutron.git propagate datastore exceptions all the way to northbound Instead of logging but ultimately ignoring them, as they currently are. Stumbled across this wile working on (not directly related) NEUTRON-158. This will also fix the problem raised in NEUTRON-157: We are, intentionally, changing the OptimisticLockFailedException WARN log to a DEBUG only. If it still didn't go through after RETRY_MAX (currently 2) then it will be rethrown, and that, with this, will go back up to the driver. JIRA: NEUTRON-157 Change-Id: I10b7dea0b5698db40ee7cfaa63593fb6b3c573c7 Signed-off-by: Michael Vorburger --- diff --git a/features/production/odl-neutron-northbound-api/pom.xml b/features/production/odl-neutron-northbound-api/pom.xml index 841c5372f..56ff4e631 100644 --- a/features/production/odl-neutron-northbound-api/pom.xml +++ b/features/production/odl-neutron-northbound-api/pom.xml @@ -27,6 +27,13 @@ + + org.opendaylight.infrautils + odl-infrautils-utils + 1.4.0-SNAPSHOT + xml + features + org.opendaylight.aaa odl-aaa-shiro diff --git a/neutron-hostconfig/ovs/src/main/java/org/opendaylight/neutron/hostconfig/ovs/NeutronHostconfigOvsListener.java b/neutron-hostconfig/ovs/src/main/java/org/opendaylight/neutron/hostconfig/ovs/NeutronHostconfigOvsListener.java index cfeeea34b..d5e2d43a0 100644 --- a/neutron-hostconfig/ovs/src/main/java/org/opendaylight/neutron/hostconfig/ovs/NeutronHostconfigOvsListener.java +++ b/neutron-hostconfig/ovs/src/main/java/org/opendaylight/neutron/hostconfig/ovs/NeutronHostconfigOvsListener.java @@ -26,6 +26,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.neutron.hostconfig.utils.NeutronHostconfigUtils; import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils; import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils; @@ -60,7 +61,8 @@ public class NeutronHostconfigOvsListener implements ClusteredDataTreeChangeList this.neutronHostconfig = new NeutronHostconfigUtils(dataBroker); } - private void processChanges(Collection> changes) { + private void processChanges(Collection> changes) + throws TransactionCommitFailedException { LOG.info("onDataTreeChanged: Received Data Tree Changed ...", changes); for (DataTreeModification change : changes) { final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); @@ -88,7 +90,11 @@ public class NeutronHostconfigOvsListener implements ClusteredDataTreeChangeList @Override public void onDataTreeChanged(@Nonnull Collection> changes) { Preconditions.checkNotNull(changes, "Changes may not be null!"); - processChanges(changes); + try { + processChanges(changes); + } catch (TransactionCommitFailedException e) { + LOG.error("Transaction commit failed; ignorining changes: ", changes, e); + } } private InstanceIdentifier createNodeIdentifier() { @@ -115,7 +121,8 @@ public class NeutronHostconfigOvsListener implements ClusteredDataTreeChangeList } } - private void updateHostConfig(Node node, NeutronHostconfigUtils.Action action) { + private void updateHostConfig(Node node, NeutronHostconfigUtils.Action action) + throws TransactionCommitFailedException { String hostId = getExternalId(node, OS_HOST_CONFIG_HOST_ID_KEY); if (hostId == null) { return; diff --git a/neutron-hostconfig/utils/src/main/java/org/opendaylight/neutron/hostconfig/utils/NeutronHostconfigUtils.java b/neutron-hostconfig/utils/src/main/java/org/opendaylight/neutron/hostconfig/utils/NeutronHostconfigUtils.java index b8090a263..ce5f259c4 100644 --- a/neutron-hostconfig/utils/src/main/java/org/opendaylight/neutron/hostconfig/utils/NeutronHostconfigUtils.java +++ b/neutron-hostconfig/utils/src/main/java/org/opendaylight/neutron/hostconfig/utils/NeutronHostconfigUtils.java @@ -8,11 +8,10 @@ package org.opendaylight.neutron.hostconfig.utils; -import java.util.concurrent.ExecutionException; - import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.Hostconfigs; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.Hostconfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.HostconfigBuilder; @@ -35,33 +34,29 @@ public class NeutronHostconfigUtils { this.dataBroker = dataBroker; } - public void updateMdsal(Hostconfig hostConfig, Action action) { + public void updateMdsal(Hostconfig hostConfig, Action action) throws TransactionCommitFailedException { InstanceIdentifier hostConfigId; if (hostConfig == null) { return; } - try { - switch (action) { - case ADD: - case UPDATE: - final WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction(); - hostConfigId = createInstanceIdentifier(hostConfig); - writeTx.put(LogicalDatastoreType.OPERATIONAL, hostConfigId, hostConfig, true); - writeTx.submit().get(); - LOG.trace("Hostconfig updated for node {}", hostConfig.getHostId()); - break; - case DELETE: - final WriteTransaction delTx = dataBroker.newWriteOnlyTransaction(); - hostConfigId = createInstanceIdentifier(hostConfig); - delTx.delete(LogicalDatastoreType.OPERATIONAL, hostConfigId); - LOG.trace("Hostconfig deleted for node {}", hostConfig.getHostId()); - delTx.submit().get(); - break; - default: - break; - } - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Hostconfig transaction commit failed to DS.", e); + switch (action) { + case ADD: + case UPDATE: + final WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction(); + hostConfigId = createInstanceIdentifier(hostConfig); + writeTx.put(LogicalDatastoreType.OPERATIONAL, hostConfigId, hostConfig, true); + writeTx.submit().checkedGet(); + LOG.trace("Hostconfig updated for node {}", hostConfig.getHostId()); + break; + case DELETE: + final WriteTransaction delTx = dataBroker.newWriteOnlyTransaction(); + hostConfigId = createInstanceIdentifier(hostConfig); + delTx.delete(LogicalDatastoreType.OPERATIONAL, hostConfigId); + LOG.trace("Hostconfig deleted for node {}", hostConfig.getHostId()); + delTx.submit().checkedGet(); + break; + default: + break; } } diff --git a/neutron-hostconfig/vpp/src/main/java/org/opendaylight/neutron/hostconfig/vpp/NeutronHostconfigVppListener.java b/neutron-hostconfig/vpp/src/main/java/org/opendaylight/neutron/hostconfig/vpp/NeutronHostconfigVppListener.java index c9aca8ea5..64d791618 100644 --- a/neutron-hostconfig/vpp/src/main/java/org/opendaylight/neutron/hostconfig/vpp/NeutronHostconfigVppListener.java +++ b/neutron-hostconfig/vpp/src/main/java/org/opendaylight/neutron/hostconfig/vpp/NeutronHostconfigVppListener.java @@ -26,6 +26,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.neutron.hostconfig.utils.NeutronHostconfigUtils; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus; @@ -81,13 +82,19 @@ public class NeutronHostconfigVppListener implements ClusteredDataTreeChangeList public void onDataTreeChanged(@Nonnull Collection> changes) { LOG.info("onDataTreeChanged: Received Data Tree Changed ...", changes); executorService.execute(() -> { - for (DataTreeModification change : Preconditions.checkNotNull(changes, "Changes may not be null!")) { - processDataTreeModification(change); + try { + for (DataTreeModification change : Preconditions.checkNotNull(changes, + "Changes may not be null!")) { + processDataTreeModification(change); + } + } catch (TransactionCommitFailedException e) { + LOG.error("Transaction commit failed; ignorining changes: ", changes, e); } }); } - private void processDataTreeModification(DataTreeModification change) { + private void processDataTreeModification(DataTreeModification change) + throws TransactionCommitFailedException { final InstanceIdentifier key = change.getRootPath().getRootIdentifier(); final DataObjectModification mod = change.getRootNode(); LOG.info("onDataTreeChanged: Received Data Tree Changed Update of Type={} for Key={}", @@ -124,7 +131,8 @@ public class NeutronHostconfigVppListener implements ClusteredDataTreeChangeList LOG.info("Registered listener to netconf nodes {}.", dataTreeIdentifier.getRootIdentifier()); } - private void updateHostConfig(Node node, NeutronHostconfigUtils.Action action) { + private void updateHostConfig(Node node, NeutronHostconfigUtils.Action action) + throws TransactionCommitFailedException { for (Map.Entry entry : HostconfigUtil.createHostconfigsDataFor(node.getNodeId(), socketInfo) .entrySet()) { LOG.info("Updating hostconfig for node {}. Action: {}.", node.key(), action); diff --git a/neutron-spi/pom.xml b/neutron-spi/pom.xml index fc384504e..ec0a5ab11 100644 --- a/neutron-spi/pom.xml +++ b/neutron-spi/pom.xml @@ -23,6 +23,7 @@ ODL :: neutron :: ${project.artifactId} + org.opendaylight.neutron @@ -45,6 +46,10 @@ org.opendaylight.controller sal-binding-api + + org.opendaylight.controller + sal-common-api + commons-net commons-net @@ -78,10 +83,4 @@ test - - scm:git:ssh://git.opendaylight.org:29418/neutron.git - scm:git:ssh://git.opendaylight.org:29418/neutron.git - HEAD - https://wiki.opendaylight.org/view/NeutronNorthBound:Main - diff --git a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronCRUD.java b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronCRUD.java index 2d3eddf07..616d5caa1 100644 --- a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronCRUD.java +++ b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronCRUD.java @@ -9,6 +9,8 @@ package org.opendaylight.neutron.spi; import java.util.List; import org.opendaylight.controller.md.sal.binding.api.ReadTransaction; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.yangtools.yang.common.OperationFailedException; /** * This interface defines the methods for CRUD of NB neutron objects. @@ -22,8 +24,9 @@ public interface INeutronCRUD> { * @param uuid UUID of the Neutron object * @param tx the ReadTransaction within which to perform the check * @return boolean + * @throws ReadFailedException if the read failed */ - boolean exists(String uuid, ReadTransaction tx); + boolean exists(String uuid, ReadTransaction tx) throws ReadFailedException; /** * Applications call this interface method to return if a particular @@ -33,15 +36,17 @@ public interface INeutronCRUD> { * UUID of the Neutron object * @return {@link org.opendaylight.neutron.spi.INeutronObject} * OpenStack Neutron class + * @throws ReadFailedException if the read failed */ - T get(String uuid); + T get(String uuid) throws ReadFailedException; /** * Applications call this interface method to return all Neutron objects. * * @return List of OpenStackNeutrons objects + * @throws ReadFailedRuntimeException if the read failed */ - List getAll(); + List getAll() throws ReadFailedRuntimeException; /** * Applications call this interface method to add a Neutron object to the @@ -50,8 +55,9 @@ public interface INeutronCRUD> { * @param input * OpenStackNeutron object * @return result with indication on whether the object was added or not and if so why + * @throws OperationFailedException if the write (or a required implicit read) failed */ - Result add(T input); + Result add(T input) throws OperationFailedException; /** * Applications call this interface method to remove a Neutron object to the @@ -60,8 +66,9 @@ public interface INeutronCRUD> { * @param uuid * identifier for the neutron object * @return boolean on whether the object was removed or not + * @throws OperationFailedException if the remove (or a required implicit read) failed */ - boolean remove(String uuid); + boolean remove(String uuid) throws OperationFailedException; /** * Applications call this interface method to edit a Neutron object. @@ -71,10 +78,10 @@ public interface INeutronCRUD> { * @param delta * OpenStackNeutron object containing changes to apply * @return boolean on whether the object was updated or not + * @throws OperationFailedException if the update (or a required implicit read) failed */ - Result update(String uuid, T delta); + Result update(String uuid, T delta) throws OperationFailedException; - enum Result { Success, AlreadyExists, DoesNotExist, DependencyMissing, Exception } - // TODO The Result "Exception" should eventually be replaced by propagating exceptions, and removed + enum Result { Success, AlreadyExists, DoesNotExist, DependencyMissing } } diff --git a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronLoadBalancerPoolCRUD.java b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronLoadBalancerPoolCRUD.java index 77a479ca7..ada8df0dc 100644 --- a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronLoadBalancerPoolCRUD.java +++ b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/INeutronLoadBalancerPoolCRUD.java @@ -8,6 +8,8 @@ package org.opendaylight.neutron.spi; import java.util.List; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.yangtools.yang.common.OperationFailedException; /** * This interface defines the methods for CRUD of NB OpenStack LoadBalancerPool objects. @@ -23,8 +25,9 @@ public interface INeutronLoadBalancerPoolCRUD extends INeutronCRUD getAllNeutronLoadBalancerPoolMembers(String poolUuid); + List getAllNeutronLoadBalancerPoolMembers(String poolUuid) + throws ReadFailedException; /** * Applications call this interface method to add a NeutronLoadBalancerPoolMember object to the @@ -57,8 +64,10 @@ public interface INeutronLoadBalancerPoolCRUD extends INeutronCRUD { * @param tapFlowUUID * UUID of Tap Flow * @return boolean on whether the object was added or not + * @throws ReadFailedException if the read failed */ - boolean tapFlowExists(String tapServiceUUID, String tapFlowUUID); + boolean tapFlowExists(String tapServiceUUID, String tapFlowUUID) throws ReadFailedException; /** * Applications call this interface method to get a NeutronTapFlow object. @@ -32,9 +37,9 @@ public interface INeutronTapFlowCRUD extends INeutronCRUD { * @param tapFlowUUID * UUID of Tap Flow * @return NeutronTapFlow object + * @throws ReadFailedException if the read failed */ - - NeutronTapFlow getTapFlow(String tapServiceUUID, String tapFlowUUID); + NeutronTapFlow getTapFlow(String tapServiceUUID, String tapFlowUUID) throws ReadFailedException; /** * Applications call this interface method to add a NeutronTapFlow object to the @@ -43,9 +48,9 @@ public interface INeutronTapFlowCRUD extends INeutronCRUD { * @param input * OpenStackNetwork object * @return boolean on whether the object was added or not + * @throws OperationFailedException if the read or write failed */ - - boolean addTapFlow(NeutronTapFlow input); + boolean addTapFlow(NeutronTapFlow input) throws ReadFailedException, OperationFailedException; /** * Applications call this interface method to update a NeutronTapFlow object to the @@ -53,10 +58,9 @@ public interface INeutronTapFlowCRUD extends INeutronCRUD { * * @param input * OpenStackNetwork object - * @return boolean on whether the object was added or not + * @throws TransactionCommitFailedException if the write failed */ - - boolean updateTapFlow(NeutronTapFlow input); + void updateTapFlow(NeutronTapFlow input) throws TransactionCommitFailedException; /** * Applications call this interface method to delete a NeutronTapFlow object. @@ -65,8 +69,7 @@ public interface INeutronTapFlowCRUD extends INeutronCRUD { * UUID of Tap Service * @param tapFlowUUID * UUID of Tap Flow - * @return boolean on whether the object was added or not + * @throws TransactionCommitFailedException if the write failed */ - - boolean deleteTapFlow(String tapServiceUUID, String tapFlowUUID); + void deleteTapFlow(String tapServiceUUID, String tapFlowUUID) throws TransactionCommitFailedException; } diff --git a/neutron-spi/src/main/java/org/opendaylight/neutron/spi/ReadFailedRuntimeException.java b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/ReadFailedRuntimeException.java new file mode 100644 index 000000000..90130c14f --- /dev/null +++ b/neutron-spi/src/main/java/org/opendaylight/neutron/spi/ReadFailedRuntimeException.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018 Red Hat, 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.neutron.spi; + +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; + +/** + * {@link ReadFailedException} as an unchecked RuntimeException. + * See also org.opendaylight.neutron.northbound.api.DatastoreOperationFailedWebApplicationException. + * + * @author Michael Vorburger.ch + */ +public class ReadFailedRuntimeException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public ReadFailedRuntimeException(ReadFailedException cause) { + super(cause); + } +} diff --git a/northbound-api/pom.xml b/northbound-api/pom.xml index a4a398581..4ea75205e 100644 --- a/northbound-api/pom.xml +++ b/northbound-api/pom.xml @@ -37,6 +37,10 @@ + + org.opendaylight.controller + sal-common-api + org.codehaus.enunciate enunciate-core-annotations diff --git a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/AbstractNeutronNorthbound.java b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/AbstractNeutronNorthbound.java index 39a9b4d34..bb9158f53 100644 --- a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/AbstractNeutronNorthbound.java +++ b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/AbstractNeutronNorthbound.java @@ -20,6 +20,7 @@ import javax.ws.rs.core.Response; import org.opendaylight.neutron.spi.INeutronCRUD; import org.opendaylight.neutron.spi.INeutronCRUD.Result; import org.opendaylight.neutron.spi.INeutronObject; +import org.opendaylight.yangtools.yang.common.OperationFailedException; public abstract class AbstractNeutronNorthbound, R extends INeutronRequest, I extends INeutronCRUD> { @@ -81,42 +82,49 @@ public abstract class AbstractNeutronNorthbound, R e return this.neutronCRUD; } - protected Response show(String uuid, - // return fields - List fields) { - T ans = neutronCRUD.get(uuid); - if (ans == null) { - throw new ResourceNotFoundException(uuidNoExist()); - } + protected Response show(String uuid, List returnFields) + throws DatastoreOperationFailedWebApplicationException { + try { + T ans = neutronCRUD.get(uuid); + if (ans == null) { + throw new ResourceNotFoundException(uuidNoExist()); + } - if (fields.size() > 0) { - return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(ans.extractFields(fields))) - .build(); - } else { - return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(ans)).build(); + if (returnFields.size() > 0) { + return Response.status(HttpURLConnection.HTTP_OK) + .entity(newNeutronRequest(ans.extractFields(returnFields))).build(); + } else { + return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(ans)).build(); + } + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } } - protected Response create(final R input) { - if (input.isSingleton()) { - T singleton = input.getSingleton(); + protected Response create(final R input) throws DatastoreOperationFailedWebApplicationException { + try { + if (input.isSingleton()) { + T singleton = input.getSingleton(); - singleton.initDefaults(); - if (neutronCRUD.add(singleton).equals(DependencyMissing)) { - return Response.status(HTTP_MISSING_DEPENDENCY).entity(input).build(); - } - } else { - if (input.getBulk() == null) { - throw new BadRequestException("Invalid requests"); - } - for (T test : input.getBulk()) { - test.initDefaults(); - if (neutronCRUD.add(test).equals(DependencyMissing)) { + singleton.initDefaults(); + if (neutronCRUD.add(singleton).equals(DependencyMissing)) { return Response.status(HTTP_MISSING_DEPENDENCY).entity(input).build(); } + } else { + if (input.getBulk() == null) { + throw new BadRequestException("Invalid requests"); + } + for (T test : input.getBulk()) { + test.initDefaults(); + if (neutronCRUD.add(test).equals(DependencyMissing)) { + return Response.status(HTTP_MISSING_DEPENDENCY).entity(input).build(); + } + } } + return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build(); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build(); } protected void updateDelta(String uuid, T delta, T original) { @@ -137,40 +145,46 @@ public abstract class AbstractNeutronNorthbound, R e return false; } - protected Response update(String uuid, final R input) { + protected Response update(String uuid, final R input) throws DatastoreOperationFailedWebApplicationException { if (!input.isSingleton()) { throw new BadRequestException("Only singleton edit supported"); } T delta = input.getSingleton(); - T original = neutronCRUD.get(uuid); - if (original == null) { - throw new ResourceNotFoundException(uuidNoExist()); - } - if (checkRevisionNumber(original, delta)) { - return Response.status(HttpURLConnection.HTTP_OK).build(); - } - updateDelta(uuid, delta, original); - /* - * update the object and return it - */ - Result updateResult = neutronCRUD.update(uuid, delta); - if (updateResult.equals(DoesNotExist)) { - throw new ResourceNotFoundException(uuidNoExist()); - } else if (updateResult.equals(DependencyMissing)) { - return Response.status(HTTP_MISSING_DEPENDENCY).entity(input).build(); + try { + T original = neutronCRUD.get(uuid); + if (original == null) { + throw new ResourceNotFoundException(uuidNoExist()); + } + if (checkRevisionNumber(original, delta)) { + return Response.status(HttpURLConnection.HTTP_OK).build(); + } + updateDelta(uuid, delta, original); + /* + * update the object and return it + */ + Result updateResult = neutronCRUD.update(uuid, delta); + if (updateResult.equals(DoesNotExist)) { + throw new ResourceNotFoundException(uuidNoExist()); + } else if (updateResult.equals(DependencyMissing)) { + return Response.status(HTTP_MISSING_DEPENDENCY).entity(input).build(); + } + T updated = neutronCRUD.get(uuid); + return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(updated)).build(); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - T updated = neutronCRUD.get(uuid); - return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(updated)).build(); } - protected Response delete(String uuid) { - /* - * remove it and return 204 status - */ - if (!neutronCRUD.remove(uuid)) { - throw new ResourceNotFoundException(uuidNoExist()); + protected Response delete(String uuid) throws DatastoreOperationFailedWebApplicationException { + try { + // remove it and return 204 status + if (!neutronCRUD.remove(uuid)) { + throw new ResourceNotFoundException(uuidNoExist()); + } else { + return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build(); + } + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - - return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build(); } } diff --git a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/DatastoreOperationFailedWebApplicationException.java b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/DatastoreOperationFailedWebApplicationException.java new file mode 100644 index 000000000..e869d0a7e --- /dev/null +++ b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/DatastoreOperationFailedWebApplicationException.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Red Hat, 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.neutron.northbound.api; + +import javax.ws.rs.WebApplicationException; +import org.opendaylight.neutron.spi.ReadFailedRuntimeException; +import org.opendaylight.yangtools.yang.common.OperationFailedException; + +/** + * JAX RS specific exception wrapping an ODL MDSAL datastore read/validate/write operation failure. + * + * @see ReadFailedRuntimeException + * + * @author Michael Vorburger.ch + */ +public class DatastoreOperationFailedWebApplicationException extends WebApplicationException { + private static final long serialVersionUID = 1L; + + public DatastoreOperationFailedWebApplicationException(OperationFailedException cause) { + super(cause); + } + +} diff --git a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronLoadBalancerPoolNorthbound.java b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronLoadBalancerPoolNorthbound.java index 310c59a50..f14341b20 100644 --- a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronLoadBalancerPoolNorthbound.java +++ b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronLoadBalancerPoolNorthbound.java @@ -7,6 +7,8 @@ */ package org.opendaylight.neutron.northbound.api; +import static java.net.HttpURLConnection.HTTP_OK; + import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.List; @@ -27,9 +29,11 @@ import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD; import org.opendaylight.neutron.spi.NeutronLoadBalancerPool; import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember; +import org.opendaylight.yangtools.yang.common.OperationFailedException; import org.ops4j.pax.cdi.api.OsgiService; /** @@ -202,35 +206,39 @@ public final class NeutronLoadBalancerPoolNorthbound extends AbstractNeutronNort // sorting not supported ) { INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); - try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) { - if (!loadBalancerPoolInterface.exists(loadBalancerPoolUUID, tx)) { - throw new ResourceNotFoundException(uuidNoExist()); + try { + try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) { + if (!loadBalancerPoolInterface.exists(loadBalancerPoolUUID, tx)) { + throw new ResourceNotFoundException(uuidNoExist()); + } } - } - List members = loadBalancerPoolInterface.get(loadBalancerPoolUUID) - .getLoadBalancerPoolMembers(); - List ans = new ArrayList<>(); - for (NeutronLoadBalancerPoolMember nsg : members) { - if ((queryLoadBalancerPoolMemberID == null || queryLoadBalancerPoolMemberID.equals(nsg.getID())) - && loadBalancerPoolUUID.equals(nsg.getPoolID()) - && (queryLoadBalancerPoolMemberTenantID == null - || queryLoadBalancerPoolMemberTenantID.equals(nsg.getTenantID())) - && (queryLoadBalancerPoolMemberAddress == null - || queryLoadBalancerPoolMemberAddress.equals(nsg.getPoolMemberAddress())) - && (queryLoadBalancerPoolMemberAdminStateUp == null - || queryLoadBalancerPoolMemberAdminStateUp.equals(nsg.getPoolMemberAdminStateIsUp())) - && (queryLoadBalancerPoolMemberWeight == null - || queryLoadBalancerPoolMemberWeight.equals(nsg.getPoolMemberWeight())) - && (queryLoadBalancerPoolMemberSubnetID == null - || queryLoadBalancerPoolMemberSubnetID.equals(nsg.getPoolMemberSubnetID()))) { - if (fields.size() > 0) { - ans.add(nsg.extractFields(fields)); - } else { - ans.add(nsg); + List members = loadBalancerPoolInterface.get(loadBalancerPoolUUID) + .getLoadBalancerPoolMembers(); + List ans = new ArrayList<>(); + for (NeutronLoadBalancerPoolMember nsg : members) { + if ((queryLoadBalancerPoolMemberID == null || queryLoadBalancerPoolMemberID.equals(nsg.getID())) + && loadBalancerPoolUUID.equals(nsg.getPoolID()) + && (queryLoadBalancerPoolMemberTenantID == null + || queryLoadBalancerPoolMemberTenantID.equals(nsg.getTenantID())) + && (queryLoadBalancerPoolMemberAddress == null + || queryLoadBalancerPoolMemberAddress.equals(nsg.getPoolMemberAddress())) + && (queryLoadBalancerPoolMemberAdminStateUp == null + || queryLoadBalancerPoolMemberAdminStateUp.equals(nsg.getPoolMemberAdminStateIsUp())) + && (queryLoadBalancerPoolMemberWeight == null + || queryLoadBalancerPoolMemberWeight.equals(nsg.getPoolMemberWeight())) + && (queryLoadBalancerPoolMemberSubnetID == null + || queryLoadBalancerPoolMemberSubnetID.equals(nsg.getPoolMemberSubnetID()))) { + if (fields.size() > 0) { + ans.add(nsg.extractFields(fields)); + } else { + ans.add(nsg); + } } } + return Response.status(HTTP_OK).entity(new NeutronLoadBalancerPoolMemberRequest(ans)).build(); + } catch (ReadFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerPoolMemberRequest(ans)).build(); } /** @@ -249,28 +257,32 @@ public final class NeutronLoadBalancerPoolNorthbound extends AbstractNeutronNort // return fields @QueryParam("fields") List fields) { - INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); - try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) { - if (!loadBalancerPoolInterface.exists(loadBalancerPoolUUID, tx)) { - throw new ResourceNotFoundException(uuidNoExist()); - } - } - List members = loadBalancerPoolInterface.get(loadBalancerPoolUUID) - .getLoadBalancerPoolMembers(); - for (NeutronLoadBalancerPoolMember ans : members) { - if (!ans.getID().equals(loadBalancerPoolMemberUUID)) { - continue; + try { + INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); + try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) { + if (!loadBalancerPoolInterface.exists(loadBalancerPoolUUID, tx)) { + throw new ResourceNotFoundException(uuidNoExist()); + } } + List members = loadBalancerPoolInterface.get(loadBalancerPoolUUID) + .getLoadBalancerPoolMembers(); + for (NeutronLoadBalancerPoolMember ans : members) { + if (!ans.getID().equals(loadBalancerPoolMemberUUID)) { + continue; + } - if (fields.size() > 0) { - return Response.status(HttpURLConnection.HTTP_OK) - .entity(new NeutronLoadBalancerPoolMemberRequest(ans.extractFields(fields))).build(); - } else { - return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerPoolMemberRequest(ans)) - .build(); + if (fields.size() > 0) { + return Response.status(HttpURLConnection.HTTP_OK) + .entity(new NeutronLoadBalancerPoolMemberRequest(ans.extractFields(fields))).build(); + } else { + return Response.status(HttpURLConnection.HTTP_OK) + .entity(new NeutronLoadBalancerPoolMemberRequest(ans)).build(); + } } + throw new ResourceNotFoundException(uuidNoExist()); + } catch (ReadFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - throw new ResourceNotFoundException(uuidNoExist()); } /** @@ -284,26 +296,29 @@ public final class NeutronLoadBalancerPoolNorthbound extends AbstractNeutronNort @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") }) public Response createLoadBalancerPoolMember(@PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID, final NeutronLoadBalancerPoolMemberRequest input) { + try { + INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); - INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); - - if (input.isSingleton()) { - NeutronLoadBalancerPoolMember singleton = input.getSingleton(); - singleton.setPoolID(loadBalancerPoolUUID); - /** - * Add the member from the neutron load balancer pool as well - */ + if (input.isSingleton()) { + NeutronLoadBalancerPoolMember singleton = input.getSingleton(); + singleton.setPoolID(loadBalancerPoolUUID); + /** + * Add the member from the neutron load balancer pool as well + */ - loadBalancerPoolInterface.addNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, singleton); - } else { - /* - * now, each element of the bulk request can be added to the cache - */ - for (NeutronLoadBalancerPoolMember test : input.getBulk()) { - loadBalancerPoolInterface.addNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, test); + loadBalancerPoolInterface.addNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, singleton); + } else { + /* + * now, each element of the bulk request can be added to the cache + */ + for (NeutronLoadBalancerPoolMember test : input.getBulk()) { + loadBalancerPoolInterface.addNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, test); + } } + return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build(); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build(); } /** @@ -318,17 +333,21 @@ public final class NeutronLoadBalancerPoolNorthbound extends AbstractNeutronNort public Response updateLoadBalancerPoolMember(@PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID, @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID, final NeutronLoadBalancerPoolMemberRequest input) { - INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); - NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.get(loadBalancerPoolUUID); - NeutronLoadBalancerPoolMember singleton = input.getSingleton(); - singleton.setPoolID(loadBalancerPoolUUID); + try { + INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); + NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.get(loadBalancerPoolUUID); + NeutronLoadBalancerPoolMember singleton = input.getSingleton(); + singleton.setPoolID(loadBalancerPoolUUID); - if (singletonPool == null) { - throw new ResourceNotFoundException("Pool doesn't Exist"); + if (singletonPool == null) { + throw new ResourceNotFoundException("Pool doesn't Exist"); + } + loadBalancerPoolInterface.updateNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, + loadBalancerPoolMemberUUID, singleton); + return Response.status(HttpURLConnection.HTTP_OK).entity(input).build(); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - loadBalancerPoolInterface.updateNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, loadBalancerPoolMemberUUID, - singleton); - return Response.status(HttpURLConnection.HTTP_OK).entity(input).build(); } /** @@ -341,27 +360,31 @@ public final class NeutronLoadBalancerPoolNorthbound extends AbstractNeutronNort @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") }) public Response deleteLoadBalancerPoolMember(@PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID, @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID) { - INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); - - //Verify that the LB pool member exists - NeutronLoadBalancerPoolMember singleton = null; - List members = loadBalancerPoolInterface.get(loadBalancerPoolUUID) - .getLoadBalancerPoolMembers(); - for (NeutronLoadBalancerPoolMember member : members) { - if (member.getID().equals(loadBalancerPoolMemberUUID)) { - singleton = member; - break; + try { + INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronCRUD(); + // Verify that the LB pool member exists + NeutronLoadBalancerPoolMember singleton = null; + List members = loadBalancerPoolInterface.get(loadBalancerPoolUUID) + .getLoadBalancerPoolMembers(); + for (NeutronLoadBalancerPoolMember member : members) { + if (member.getID().equals(loadBalancerPoolMemberUUID)) { + singleton = member; + break; + } + } + if (singleton == null) { + throw new BadRequestException("LoadBalancerPoolMember UUID does not exist."); } - } - if (singleton == null) { - throw new BadRequestException("LoadBalancerPoolMember UUID does not exist."); - } - /** - * Remove the member from the neutron load balancer pool - */ - loadBalancerPoolInterface.removeNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, loadBalancerPoolMemberUUID); + /** + * Remove the member from the neutron load balancer pool + */ + loadBalancerPoolInterface.removeNeutronLoadBalancerPoolMember(loadBalancerPoolUUID, + loadBalancerPoolMemberUUID); - return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build(); + return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build(); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); + } } } diff --git a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronMeteringLabelRulesNorthbound.java b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronMeteringLabelRulesNorthbound.java index dd1b6ad9c..887d4738e 100644 --- a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronMeteringLabelRulesNorthbound.java +++ b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronMeteringLabelRulesNorthbound.java @@ -26,6 +26,7 @@ import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; import org.opendaylight.neutron.spi.INeutronMeteringLabelRuleCRUD; import org.opendaylight.neutron.spi.NeutronMeteringLabelRule; +import org.opendaylight.yangtools.yang.common.OperationFailedException; import org.ops4j.pax.cdi.api.OsgiService; /** @@ -116,22 +117,21 @@ public final class NeutronMeteringLabelRulesNorthbound extends AbstractNeutronNo @StatusCodes({ @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"), @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") }) public Response createMeteringLabelRule(final NeutronMeteringLabelRuleRequest input) { - INeutronMeteringLabelRuleCRUD meteringLabelRuleInterface = getNeutronCRUD(); if (input.isSingleton()) { NeutronMeteringLabelRule singleton = input.getSingleton(); + try { + // add meteringLabelRule to the cache + INeutronMeteringLabelRuleCRUD meteringLabelRuleInterface = getNeutronCRUD(); + meteringLabelRuleInterface.add(singleton); + return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build(); - /* - * add meteringLabelRule to the cache - */ - meteringLabelRuleInterface.add(singleton); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); + } } else { - - /* - * only singleton meteringLabelRule creates supported - */ + // only singleton meteringLabelRule creates supported throw new BadRequestException("Only singleton meteringLabelRule creates supported"); } - return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build(); } /** diff --git a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronTapFlowNorthbound.java b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronTapFlowNorthbound.java index ee8429c83..8f97da504 100644 --- a/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronTapFlowNorthbound.java +++ b/northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronTapFlowNorthbound.java @@ -25,8 +25,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.neutron.spi.INeutronTapFlowCRUD; import org.opendaylight.neutron.spi.NeutronTapFlow; +import org.opendaylight.yangtools.yang.common.OperationFailedException; import org.ops4j.pax.cdi.api.OsgiService; @Singleton @@ -108,7 +110,11 @@ public final class NeutronTapFlowNorthbound NeutronTapFlow singleton = input.getSingleton(); singleton.setTapFlowServiceID(tapServiceUUID); - tapFlowInterface.addTapFlow(singleton); + try { + tapFlowInterface.addTapFlow(singleton); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); + } } else { throw new BadRequestException("Only Singleton tapFlow creation supported"); } @@ -130,19 +136,22 @@ public final class NeutronTapFlowNorthbound public Response showTapFlow(@PathParam("tapServiceUUID") String tapServiceUUID, @PathParam("tapFlowUUID") String tapFlowUUID, @QueryParam("fields") List fields) { + try { + INeutronTapFlowCRUD tapFlowInterface = getNeutronCRUD(); + if (!tapFlowInterface.tapFlowExists(tapServiceUUID, tapFlowUUID)) { + throw new ResourceNotFoundException("Specified UUID does not Exist"); + } - INeutronTapFlowCRUD tapFlowInterface = getNeutronCRUD(); - if (!tapFlowInterface.tapFlowExists(tapServiceUUID, tapFlowUUID)) { - throw new ResourceNotFoundException("Specified UUID does not Exist"); - } - - NeutronTapFlow tapFlow = tapFlowInterface.getTapFlow(tapServiceUUID, tapFlowUUID); - if (fields.size() > 0) { - return Response.status(HttpURLConnection.HTTP_OK) - .entity(new NeutronTapFlowRequest(tapFlow.extractFields(fields))).build(); - } else { - return Response.status(HttpURLConnection.HTTP_OK) - .entity(new NeutronTapFlowRequest(tapFlow)).build(); + NeutronTapFlow tapFlow = tapFlowInterface.getTapFlow(tapServiceUUID, tapFlowUUID); + if (fields.size() > 0) { + return Response.status(HttpURLConnection.HTTP_OK) + .entity(new NeutronTapFlowRequest(tapFlow.extractFields(fields))).build(); + } else { + return Response.status(HttpURLConnection.HTTP_OK) + .entity(new NeutronTapFlowRequest(tapFlow)).build(); + } + } catch (ReadFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } } @@ -159,18 +168,21 @@ public final class NeutronTapFlowNorthbound public Response updateTapFlow(@PathParam("tapServiceUUID") String tapServiceUUID, @PathParam("tapFlowUUID") String tapFlowUUID, final NeutronTapFlowRequest input) { + try { + INeutronTapFlowCRUD tapFlowInterface = getNeutronCRUD(); - INeutronTapFlowCRUD tapFlowInterface = getNeutronCRUD(); - - if (!tapFlowInterface.tapFlowExists(tapServiceUUID, tapFlowUUID)) { - throw new ResourceNotFoundException("Specified UUID does not Exist"); - } + if (!tapFlowInterface.tapFlowExists(tapServiceUUID, tapFlowUUID)) { + throw new ResourceNotFoundException("Specified UUID does not Exist"); + } - NeutronTapFlow singleton = input.getSingleton(); - singleton.setTapFlowServiceID(tapServiceUUID); - tapFlowInterface.updateTapFlow(singleton); + NeutronTapFlow singleton = input.getSingleton(); + singleton.setTapFlowServiceID(tapServiceUUID); + tapFlowInterface.updateTapFlow(singleton); - return Response.status(HttpURLConnection.HTTP_OK).entity(input).build(); + return Response.status(HttpURLConnection.HTTP_OK).entity(input).build(); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); + } } /** @@ -183,14 +195,17 @@ public final class NeutronTapFlowNorthbound @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") }) public Response deleteTapFlow(@PathParam("tapServiceUUID") String tapServiceUUID, @PathParam("tapFlowUUID") String tapFlowUUID) { + try { + INeutronTapFlowCRUD tapFlowInterface = getNeutronCRUD(); - INeutronTapFlowCRUD tapFlowInterface = getNeutronCRUD(); + if (!tapFlowInterface.tapFlowExists(tapServiceUUID, tapFlowUUID)) { + throw new ResourceNotFoundException("Specified UUID does not Exist"); + } - if (!tapFlowInterface.tapFlowExists(tapServiceUUID, tapFlowUUID)) { - throw new ResourceNotFoundException("Specified UUID does not Exist"); + tapFlowInterface.deleteTapFlow(tapServiceUUID, tapFlowUUID); + return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build(); + } catch (OperationFailedException e) { + throw new DatastoreOperationFailedWebApplicationException(e); } - - tapFlowInterface.deleteTapFlow(tapServiceUUID, tapFlowUUID); - return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build(); } } diff --git a/parent/pom.xml b/parent/pom.xml index e42c2331f..d7f1f4559 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -37,6 +37,13 @@ + + org.opendaylight.infrautils + infrautils-artifacts + 1.4.0-SNAPSHOT + pom + import + org.opendaylight.controller mdsal-artifacts diff --git a/transcriber/pom.xml b/transcriber/pom.xml index d956641dd..ead53ab33 100644 --- a/transcriber/pom.xml +++ b/transcriber/pom.xml @@ -71,6 +71,10 @@ model ${project.version} + + org.opendaylight.infrautils + infrautils-util + javax.inject javax.inject diff --git a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/AbstractTranscriberInterface.java b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/AbstractTranscriberInterface.java index 5419ec08c..f3f53b3a3 100644 --- a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/AbstractTranscriberInterface.java +++ b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/AbstractTranscriberInterface.java @@ -19,8 +19,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; import javax.annotation.PreDestroy; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -33,11 +31,13 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.infrautils.utils.function.CheckedFunction; import org.opendaylight.neutron.spi.INeutronAdminAttributes; import org.opendaylight.neutron.spi.INeutronBaseAttributes; import org.opendaylight.neutron.spi.INeutronCRUD; import org.opendaylight.neutron.spi.INeutronObject; import org.opendaylight.neutron.spi.NeutronObject; +import org.opendaylight.neutron.spi.ReadFailedRuntimeException; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.attrs.rev150712.AdminAttributes; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.attrs.rev150712.BaseAttributes; @@ -49,6 +49,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.Identifiable; import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.OperationFailedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -313,37 +314,32 @@ public abstract class AbstractTranscriberInterface< protected abstract S fromMd(T dataObject); - private W readMd(InstanceIdentifier path, ReadTransaction tx) { + private W readMd(InstanceIdentifier path, ReadTransaction tx) throws ReadFailedException { Preconditions.checkNotNull(tx); W result = null; final CheckedFuture, ReadFailedException> future = tx.read(LogicalDatastoreType.CONFIGURATION, path); if (future != null) { - Optional optional; - try { - optional = future.checkedGet(); - if (optional.isPresent()) { - result = optional.get(); - } - } catch (final ReadFailedException e) { - LOG.warn("Failed to read {}", path, e); + Optional optional = future.checkedGet(); + if (optional.isPresent()) { + result = optional.get(); } } return result; } - protected W readMd(InstanceIdentifier path) { + protected W readMd(InstanceIdentifier path) throws ReadFailedException { try (ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) { return readMd(path, tx); } } - private void addMd(S neutronObject, WriteTransaction tx) throws InterruptedException, ExecutionException { + private void addMd(S neutronObject, WriteTransaction tx) throws TransactionCommitFailedException { // TODO think about adding existence logic updateMd(neutronObject, tx); } - private void updateMd(S neutronObject, WriteTransaction tx) throws InterruptedException, ExecutionException { + private void updateMd(S neutronObject, WriteTransaction tx) throws TransactionCommitFailedException { Preconditions.checkNotNull(tx); final T item = toMd(neutronObject); @@ -351,16 +347,16 @@ public abstract class AbstractTranscriberInterface< tx.put(LogicalDatastoreType.CONFIGURATION, iid, item, true); final CheckedFuture future = tx.submit(); // Check if it's successfully committed, otherwise exception will be thrown. - future.get(); + future.checkedGet(); } - private void removeMd(T item, WriteTransaction tx) throws InterruptedException, ExecutionException { + private void removeMd(T item, WriteTransaction tx) throws TransactionCommitFailedException { Preconditions.checkNotNull(tx); final InstanceIdentifier iid = createInstanceIdentifier(item); tx.delete(LogicalDatastoreType.CONFIGURATION, iid); final CheckedFuture future = tx.submit(); // Check if it's successfully committed, otherwise exception will be thrown. - future.get(); + future.checkedGet(); } protected static Uuid toUuid(String uuid) { @@ -391,13 +387,13 @@ public abstract class AbstractTranscriberInterface< } @Override - public boolean exists(String uuid, ReadTransaction tx) { + public boolean exists(String uuid, ReadTransaction tx) throws ReadFailedException { Preconditions.checkNotNull(tx); final T dataObject = readMd(createInstanceIdentifier(toMd(uuid)), tx); return dataObject != null; } - private S get(String uuid, ReadTransaction tx) { + private S get(String uuid, ReadTransaction tx) throws ReadFailedException { Preconditions.checkNotNull(tx); final T dataObject = readMd(createInstanceIdentifier(toMd(uuid)), tx); if (dataObject == null) { @@ -407,7 +403,7 @@ public abstract class AbstractTranscriberInterface< } @Override - public S get(String uuid) { + public S get(String uuid) throws ReadFailedException { try (ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) { return get(uuid, tx); } @@ -415,7 +411,7 @@ public abstract class AbstractTranscriberInterface< protected abstract List getDataObjectList(U dataObjects); - private List getAll(ReadTransaction tx) { + private List getAll(ReadTransaction tx) throws ReadFailedException { Preconditions.checkNotNull(tx); final Set allNeutronObjects = new HashSet<>(); final U dataObjects = readMd(createInstanceIdentifier(), tx); @@ -431,13 +427,17 @@ public abstract class AbstractTranscriberInterface< } @Override - public List getAll() { + public List getAll() throws ReadFailedRuntimeException { try (ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) { - return getAll(tx); + try { + return getAll(tx); + } catch (ReadFailedException e) { + throw new ReadFailedRuntimeException(e); + } } } - private Result add(S input, ReadWriteTransaction tx) throws InterruptedException, ExecutionException { + private Result add(S input, ReadWriteTransaction tx) throws OperationFailedException { Preconditions.checkNotNull(tx); if (exists(input.getID(), tx)) { tx.cancel(); @@ -448,8 +448,9 @@ public abstract class AbstractTranscriberInterface< } @Override - public Result add(S input) { + public Result add(S input) throws OperationFailedException { int retries = RETRY_MAX; + OptimisticLockFailedException lastOptimisticLockFailedException = null; while (retries-- >= 0) { final ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction(); try { @@ -458,22 +459,21 @@ public abstract class AbstractTranscriberInterface< } else { return Result.DependencyMissing; } - } catch (InterruptedException | ExecutionException e) { + } catch (TransactionCommitFailedException e) { // TODO replace all this with org.opendaylight.genius.infra.RetryingManagedNewTransactionRunner - if (e.getCause() instanceof OptimisticLockFailedException) { - LOG.warn("Got OptimisticLockFailedException - {} {}", input, retries); + if (e instanceof OptimisticLockFailedException) { + LOG.debug("Got OptimisticLockFailedException - {} {}", input, retries); + lastOptimisticLockFailedException = (OptimisticLockFailedException) e; continue; + } else { + throw e; } - // TODO: rethrow exception. don't mask exception - LOG.error("Transaction failed", e); } - break; } - // TODO remove when re-throwing, and remove Result.Exception completely - return Result.Exception; + throw lastOptimisticLockFailedException; } - private boolean remove(String uuid, ReadWriteTransaction tx) throws InterruptedException, ExecutionException { + private boolean remove(String uuid, ReadWriteTransaction tx) throws OperationFailedException { Preconditions.checkNotNull(tx); if (!exists(uuid, tx)) { tx.cancel(); @@ -484,27 +484,28 @@ public abstract class AbstractTranscriberInterface< } @Override - public boolean remove(String uuid) { + public boolean remove(String uuid) throws OperationFailedException { int retries = RETRY_MAX; + OptimisticLockFailedException lastOptimisticLockFailedException = null; while (retries-- >= 0) { final ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction(); try { return remove(uuid, tx); - } catch (InterruptedException | ExecutionException e) { - if (e.getCause() instanceof OptimisticLockFailedException) { - LOG.warn("Got OptimisticLockFailedException - {} {}", uuid, retries); + } catch (TransactionCommitFailedException e) { + // TODO replace all this with org.opendaylight.genius.infra.RetryingManagedNewTransactionRunner + if (e instanceof OptimisticLockFailedException) { + LOG.debug("Got OptimisticLockFailedException - {} {}", uuid, retries); + lastOptimisticLockFailedException = (OptimisticLockFailedException) e; continue; + } else { + throw e; } - // TODO: rethrow exception. don't mask exception - LOG.error("Transaction failed", e); } - break; } - return false; + throw lastOptimisticLockFailedException; } - private Result update(String uuid, S delta, ReadWriteTransaction tx) - throws InterruptedException, ExecutionException { + private Result update(String uuid, S delta, ReadWriteTransaction tx) throws OperationFailedException { Preconditions.checkNotNull(tx); if (!exists(uuid, tx)) { tx.cancel(); @@ -515,8 +516,9 @@ public abstract class AbstractTranscriberInterface< } @Override - public Result update(String uuid, S delta) { + public Result update(String uuid, S delta) throws OperationFailedException { int retries = RETRY_MAX; + OptimisticLockFailedException lastOptimisticLockFailedException = null; while (retries-- >= 0) { final ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction(); try { @@ -525,18 +527,18 @@ public abstract class AbstractTranscriberInterface< } else { return Result.DependencyMissing; } - } catch (InterruptedException | ExecutionException e) { - if (e.getCause() instanceof OptimisticLockFailedException) { - LOG.warn("Got OptimisticLockFailedException - {} {} {}", uuid, delta, retries); + } catch (TransactionCommitFailedException e) { + // TODO replace all this with org.opendaylight.genius.infra.RetryingManagedNewTransactionRunner + if (e instanceof OptimisticLockFailedException) { + LOG.debug("Got OptimisticLockFailedException - {} {} {}", uuid, delta, retries); + lastOptimisticLockFailedException = (OptimisticLockFailedException) e; continue; + } else { + throw e; } - // TODO: rethrow exception. don't mask exception - LOG.error("Transaction failed", e); } - break; } - // TODO remove when re-throwing, and remove Result.Exception completely - return Result.Exception; + throw lastOptimisticLockFailedException; } /** @@ -546,10 +548,10 @@ public abstract class AbstractTranscriberInterface< *

Implementations *MUST* use the passed in transaction. They will typically call the * {@link #exists(String, ReadTransaction)} method on ANOTHER transcriber with it. * - *

Implementations should chain {@link #ifNonNull(Object, Function)}, or perform null safe comparisons otherwise, - * for both optional non-mandatory {@link NeutronObject} as well as mandatory properties which may well be null. - * Both must mandatory and non-mandatory must be guarded, because modify (update) operation are allowed to contain - * partial neutron objects with missing fields. + *

Implementations should chain {@link #ifNonNull(Object, CheckedFunction)}, or perform null safe comparisons + * otherwise, for both optional non-mandatory {@link NeutronObject} as well as mandatory properties which may well + * be null. Both must mandatory and non-mandatory must be guarded, because modify (update) operation are allowed to + * contain partial neutron objects with missing fields. * * @param tx the transaction within which to perform reads to check for dependencies * @param neutronObject the incoming main neutron object in which there may be references to dependencies @@ -558,17 +560,21 @@ public abstract class AbstractTranscriberInterface< * {@link #add(INeutronObject)} (or {@link #update(String, INeutronObject)} operation can proceed; false if * there are unmet dependencies, which will cause the add to abort, and a respective * error code returned to the caller. + * + * @throws ReadFailedException in case of a data store problem */ - protected boolean areAllDependenciesAvailable(ReadTransaction tx, S neutronObject) { + protected boolean areAllDependenciesAvailable(ReadTransaction tx, S neutronObject) throws ReadFailedException { return true; } /** * Utility to perform well readable code of null-safe chains of e.g. * {@link #exists(String, ReadTransaction)} method calls. + * + * @throws ReadFailedException in case of a data store problem */ - protected static final boolean ifNonNull( - @Nullable X property, Function<@NonNull X, @NonNull Boolean> function) { + protected static final boolean ifNonNull(@Nullable X property, + CheckedFunction<@NonNull X, @NonNull Boolean, ReadFailedException> function) throws ReadFailedException { if (property != null) { Boolean result = function.apply(property); Preconditions.checkNotNull(result, "result"); diff --git a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronLoadBalancerPoolInterface.java b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronLoadBalancerPoolInterface.java index 2f2090e38..1f1ee0608 100644 --- a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronLoadBalancerPoolInterface.java +++ b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronLoadBalancerPoolInterface.java @@ -14,7 +14,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.ExecutionException; import javax.inject.Inject; import javax.inject.Singleton; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -44,7 +43,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.l import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.pool.members.MemberBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.pool.attributes.SessionPersistenceBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.OperationFailedException; import org.ops4j.pax.cdi.api.OsgiServiceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -138,8 +139,7 @@ public final class NeutronLoadBalancerPoolInterface answer.setLoadBalancerPoolProtocol(PROTOCOL_MAP.get(pool.getProtocol())); } if (pool.getSessionPersistence() != null) { - final NeutronLoadBalancerSessionPersistence sessionPersistence = - new NeutronLoadBalancerSessionPersistence(); + NeutronLoadBalancerSessionPersistence sessionPersistence = new NeutronLoadBalancerSessionPersistence(); sessionPersistence.setCookieName(pool.getSessionPersistence().getCookieName()); sessionPersistence.setType(pool.getSessionPersistence().getType()); @@ -149,7 +149,7 @@ public final class NeutronLoadBalancerPoolInterface } @Override - public boolean neutronLoadBalancerPoolMemberExists(String poolUuid, String uuid) { + public boolean neutronLoadBalancerPoolMemberExists(String poolUuid, String uuid) throws ReadFailedException { final Member member = readMemberMd(createMemberInstanceIdentifier(toMd(poolUuid), toMemberMd(uuid))); if (member == null) { return false; @@ -158,7 +158,8 @@ public final class NeutronLoadBalancerPoolInterface } @Override - public NeutronLoadBalancerPoolMember getNeutronLoadBalancerPoolMember(String poolUuid, String uuid) { + public NeutronLoadBalancerPoolMember getNeutronLoadBalancerPoolMember(String poolUuid, String uuid) + throws ReadFailedException { final Member member = readMemberMd(createMemberInstanceIdentifier(toMd(poolUuid), toMemberMd(uuid))); if (member == null) { return null; @@ -167,7 +168,8 @@ public final class NeutronLoadBalancerPoolInterface } @Override - public List getAllNeutronLoadBalancerPoolMembers(String poolUuid) { + public List getAllNeutronLoadBalancerPoolMembers(String poolUuid) + throws ReadFailedException { final Set allLoadBalancerPoolMembers = new HashSet<>(); final Members members = readMd(createMembersInstanceIdentifier(toMd(poolUuid))); if (members != null) { @@ -183,7 +185,8 @@ public final class NeutronLoadBalancerPoolInterface } @Override - public boolean addNeutronLoadBalancerPoolMember(String poolUuid, NeutronLoadBalancerPoolMember input) { + public boolean addNeutronLoadBalancerPoolMember(String poolUuid, NeutronLoadBalancerPoolMember input) + throws OperationFailedException { if (neutronLoadBalancerPoolMemberExists(poolUuid, input.getID())) { return false; } @@ -192,16 +195,17 @@ public final class NeutronLoadBalancerPoolInterface } @Override - public boolean removeNeutronLoadBalancerPoolMember(String poolUuid, String uuid) { + public boolean removeNeutronLoadBalancerPoolMember(String poolUuid, String uuid) throws OperationFailedException { if (!neutronLoadBalancerPoolMemberExists(poolUuid, uuid)) { return false; } - return removeMemberMd(toMd(poolUuid), toMemberMd(uuid)); + removeMemberMd(toMd(poolUuid), toMemberMd(uuid)); + return true; } @Override public boolean updateNeutronLoadBalancerPoolMember(String poolUuid, String uuid, - NeutronLoadBalancerPoolMember delta) { + NeutronLoadBalancerPoolMember delta) throws OperationFailedException { if (!neutronLoadBalancerPoolMemberExists(poolUuid, uuid)) { return false; } @@ -210,7 +214,8 @@ public final class NeutronLoadBalancerPoolInterface } @Override - public boolean neutronLoadBalancerPoolMemberInUse(String poolUuid, String loadBalancerPoolMemberID) { + public boolean neutronLoadBalancerPoolMemberInUse(String poolUuid, String loadBalancerPoolMemberID) + throws ReadFailedException { return !neutronLoadBalancerPoolMemberExists(poolUuid, loadBalancerPoolMemberID); } @@ -264,64 +269,47 @@ public final class NeutronLoadBalancerPoolInterface return memberBuilder.build(); } - protected Member toMemberMd(String uuid) { + private Member toMemberMd(String uuid) { final MemberBuilder memberBuilder = new MemberBuilder(); memberBuilder.setUuid(toUuid(uuid)); return memberBuilder.build(); } - protected < - T extends org.opendaylight.yangtools.yang.binding.DataObject> T readMemberMd(InstanceIdentifier path) { + private T readMemberMd(InstanceIdentifier path) throws ReadFailedException { T result = null; - final ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction(); - final CheckedFuture, - ReadFailedException> future = transaction.read(LogicalDatastoreType.CONFIGURATION, path); - if (future != null) { - Optional optional; - try { + try (ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction()) { + final CheckedFuture, ReadFailedException> future = transaction + .read(LogicalDatastoreType.CONFIGURATION, path); + if (future != null) { + Optional optional; optional = future.checkedGet(); if (optional.isPresent()) { result = optional.get(); } - } catch (final ReadFailedException e) { - LOG.warn("Failed to read {}", path, e); } } - transaction.close(); return result; } - protected boolean addMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) { + private void addMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) + throws TransactionCommitFailedException { // TODO think about adding existence logic - return updateMemberMd(pool, neutronObject); + updateMemberMd(pool, neutronObject); } - protected boolean updateMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) { + private void updateMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) + throws TransactionCommitFailedException { final WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction(); final Member item = toMemberMd(neutronObject); final InstanceIdentifier iid = createMemberInstanceIdentifier(pool, item); transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item, true); - final CheckedFuture future = transaction.submit(); - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Transation failed ", e); - return false; - } - return true; + transaction.submit().checkedGet(); } - protected boolean removeMemberMd(Pool pool, Member item) { + private void removeMemberMd(Pool pool, Member item) throws TransactionCommitFailedException { final WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction(); final InstanceIdentifier iid = createMemberInstanceIdentifier(pool, item); transaction.delete(LogicalDatastoreType.CONFIGURATION, iid); - final CheckedFuture future = transaction.submit(); - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Transation failed ", e); - return false; - } - return true; + transaction.submit().checkedGet(); } } diff --git a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronSecurityRuleInterface.java b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronSecurityRuleInterface.java index aa4054155..73015be0a 100644 --- a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronSecurityRuleInterface.java +++ b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronSecurityRuleInterface.java @@ -14,6 +14,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadTransaction; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.neutron.northbound.api.BadRequestException; import org.opendaylight.neutron.spi.INeutronSecurityRuleCRUD; import org.opendaylight.neutron.spi.NeutronSecurityRule; @@ -135,7 +136,8 @@ public final class NeutronSecurityRuleInterface extends } @Override - protected boolean areAllDependenciesAvailable(ReadTransaction tx, NeutronSecurityRule securityRule) { + protected boolean areAllDependenciesAvailable(ReadTransaction tx, NeutronSecurityRule securityRule) + throws ReadFailedException { return ifNonNull(securityRule.getSecurityRuleGroupID(), groupID -> securityGroupInterface.exists(groupID, tx)) && ifNonNull(securityRule.getSecurityRemoteGroupID(), diff --git a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronTapFlowInterface.java b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronTapFlowInterface.java index 39b0a88f5..38c5e5177 100644 --- a/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronTapFlowInterface.java +++ b/transcriber/src/main/java/org/opendaylight/neutron/transcriber/NeutronTapFlowInterface.java @@ -8,14 +8,13 @@ package org.opendaylight.neutron.transcriber; import com.google.common.collect.ImmutableBiMap; -import com.google.common.util.concurrent.CheckedFuture; import java.util.List; -import java.util.concurrent.ExecutionException; import javax.inject.Inject; import javax.inject.Singleton; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.neutron.spi.INeutronTapFlowCRUD; import org.opendaylight.neutron.spi.NeutronTapFlow; @@ -33,6 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.tapaas.rev171024.ta import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.tapaas.rev171024.tap.services.attributes.tap.services.TapService; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.tapaas.rev171024.tap.services.attributes.tap.services.TapServiceKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.OperationFailedException; import org.ops4j.pax.cdi.api.OsgiServiceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -104,58 +104,44 @@ public final class NeutronTapFlowInterface } @Override - public boolean tapFlowExists(String tapServiceUUID, String tapFlowUUID) { + public boolean tapFlowExists(String tapServiceUUID, String tapFlowUUID) throws ReadFailedException { final TapFlow dataObject = readMd(createTapFlowInstanceIdentifier(tapServiceUUID, toMd(tapFlowUUID))); return dataObject != null; } - private boolean tapServiceExists(String tapServiceUUID) { + private boolean tapServiceExists(String tapServiceUUID) throws ReadFailedException { final TapService tapService = readMd(InstanceIdentifier.create(Neutron.class).child(TapServices.class) .child(TapService.class, new TapServiceKey(toUuid(tapServiceUUID)))); return tapService != null; } - private boolean updateTapFlowMd(NeutronTapFlow tapFlow) { + private void updateTapFlowMd(NeutronTapFlow tapFlow) throws TransactionCommitFailedException { final WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction(); final TapFlow item = toMd(tapFlow); final InstanceIdentifier iid = createTapFlowInstanceIdentifier(tapFlow.getTapFlowServiceID(), item); transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item, true); - final CheckedFuture future = transaction.submit(); - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Transaction Failed ", e); - return false; - } - return true; + transaction.submit().checkedGet(); } - private boolean removeTapFlowMd(String tapServiceUUID, String tapFlowUUID) { + private void removeTapFlowMd(String tapServiceUUID, String tapFlowUUID) throws TransactionCommitFailedException { final WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction(); final InstanceIdentifier iid = createTapFlowInstanceIdentifier(tapServiceUUID, toMd(tapFlowUUID)); transaction.delete(LogicalDatastoreType.CONFIGURATION, iid); - final CheckedFuture future = transaction.submit(); - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { - LOG.warn("Transation failed ", e); - return false; - } - return true; + transaction.submit().checkedGet(); } - private boolean addTapFlowMd(NeutronTapFlow tapFlow) { - return updateTapFlowMd(tapFlow); + private void addTapFlowMd(NeutronTapFlow tapFlow) throws TransactionCommitFailedException { + updateTapFlowMd(tapFlow); } @Override - public boolean updateTapFlow(NeutronTapFlow tapFlow) { - return updateTapFlowMd(tapFlow); + public void updateTapFlow(NeutronTapFlow tapFlow) throws TransactionCommitFailedException { + updateTapFlowMd(tapFlow); } @Override - public boolean addTapFlow(NeutronTapFlow tapFlow) { + public boolean addTapFlow(NeutronTapFlow tapFlow) throws OperationFailedException { if (!tapServiceExists(tapFlow.getTapFlowServiceID())) { return false; } @@ -167,7 +153,7 @@ public final class NeutronTapFlowInterface } @Override - public NeutronTapFlow getTapFlow(String tapServiceUUID, String tapFlowUUID) { + public NeutronTapFlow getTapFlow(String tapServiceUUID, String tapFlowUUID) throws ReadFailedException { final TapFlow tapFlow = readMd(createTapFlowInstanceIdentifier(tapServiceUUID, toMd(tapFlowUUID))); if (tapFlow == null) { return null; @@ -176,7 +162,7 @@ public final class NeutronTapFlowInterface } @Override - public boolean deleteTapFlow(String tapServiceUUID, String tapFlowUUID) { - return removeTapFlowMd(tapServiceUUID, tapFlowUUID); + public void deleteTapFlow(String tapServiceUUID, String tapFlowUUID) throws TransactionCommitFailedException { + removeTapFlowMd(tapServiceUUID, tapFlowUUID); } }