From 9f63f7e528d7845c39c69e6b900fa80bbf4e0a17 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 22 Mar 2016 15:07:58 +0100 Subject: Move generic APIs and Utils out of reader package Change-Id: I3657da8005a5af1c003107528e16dc1d81efa85a Signed-off-by: Maros Marsalek --- .../honeycomb/v3po/impl/trans/SubtreeManager.java | 39 +++ .../v3po/impl/trans/r/SubtreeManager.java | 39 --- .../fd/honeycomb/v3po/impl/trans/r/VppReader.java | 1 + .../trans/r/impl/AbstractCompositeVppReader.java | 4 +- .../impl/trans/r/impl/CompositeChildVppReader.java | 2 +- .../impl/trans/r/impl/CompositeListVppReader.java | 2 +- .../impl/trans/r/impl/CompositeRootVppReader.java | 2 +- .../trans/r/util/DelegatingReaderRegistry.java | 1 + .../v3po/impl/trans/r/util/ReflectionUtils.java | 79 ------ .../r/util/ReflexiveChildReaderCustomizer.java | 1 + .../impl/trans/r/util/VppApiReaderCustomizer.java | 41 ---- .../v3po/impl/trans/r/util/VppRWUtils.java | 164 ------------- .../v3po/impl/trans/util/ReflectionUtils.java | 79 ++++++ .../v3po/impl/trans/util/VppApiCustomizer.java | 41 ++++ .../honeycomb/v3po/impl/trans/util/VppRWUtils.java | 164 +++++++++++++ .../v3po/impl/vppstate/BridgeDomainCustomizer.java | 6 +- .../v3po/impl/vppstate/VersionCustomizer.java | 4 +- .../io/fd/honeycomb/v3po/impl/vppstate/BdTest.java | 268 --------------------- .../honeycomb/v3po/impl/vppstate/VppStateTest.java | 268 +++++++++++++++++++++ .../v3po/impl/vppstate/VppStateUtils.java | 2 +- 20 files changed, 605 insertions(+), 602 deletions(-) create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java delete mode 100644 v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java create mode 100644 v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateTest.java (limited to 'v3po') diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java new file mode 100644 index 000000000..0aa927cd0 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.impl.trans; + +import com.google.common.annotations.Beta; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Base identifiable subtree manager(reader, writer etc.) + * + * @param Specific DataObject derived type, that is managed by this manager + */ +@Beta +public interface SubtreeManager { + + /** + * Gets the type of node managed by this reader + * + * @return Class object for node managed by this reader + */ + @Nonnull + InstanceIdentifier getManagedDataObjectType(); +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java deleted file mode 100644 index fbe17148c..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.r; - -import com.google.common.annotations.Beta; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Base identifiable subtree manager(reader, writer etc.) - * - * @param Specific DataObject derived type, that is managed by this manager - */ -@Beta -public interface SubtreeManager { - - /** - * Gets the type of node managed by this reader - * - * @return Class object for node managed by this reader - */ - @Nonnull - InstanceIdentifier getManagedDataObjectType(); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java index 8964aa769..8af493854 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java @@ -17,6 +17,7 @@ package io.fd.honeycomb.v3po.impl.trans.r; import com.google.common.annotations.Beta; +import io.fd.honeycomb.v3po.impl.trans.SubtreeManager; import java.util.List; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.binding.DataObject; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java index 456737f37..511192483 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java @@ -23,8 +23,8 @@ import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; import io.fd.honeycomb.v3po.impl.trans.r.VppReader; -import io.fd.honeycomb.v3po.impl.trans.r.util.ReflectionUtils; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import io.fd.honeycomb.v3po.impl.trans.util.ReflectionUtils; +import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java index dd7dbc499..8f425b09f 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java @@ -20,7 +20,7 @@ import com.google.common.annotations.Beta; import com.google.common.base.Optional; import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ChildVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import java.util.List; import javax.annotation.Nonnull; import javax.annotation.concurrent.ThreadSafe; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java index 74ca40696..8d23aa4e0 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java @@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkState; import com.google.common.annotations.Beta; import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ListVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java index ca972e5f8..c87600b26 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java @@ -20,7 +20,7 @@ import com.google.common.annotations.Beta; import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; import io.fd.honeycomb.v3po.impl.trans.r.VppReader; import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.RootVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import java.util.List; import javax.annotation.Nonnull; import javax.annotation.concurrent.ThreadSafe; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java index 61435d9ed..033e01b09 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java @@ -19,6 +19,7 @@ package io.fd.honeycomb.v3po.impl.trans.r.util; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.Iterables; +import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import io.fd.honeycomb.v3po.impl.trans.r.ReaderRegistry; import io.fd.honeycomb.v3po.impl.trans.r.VppReader; import java.util.ArrayList; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java deleted file mode 100644 index 790af8820..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.r.util; - -import com.google.common.base.Optional; -import java.lang.reflect.Method; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Reflection based utilities - */ -public final class ReflectionUtils { - - private ReflectionUtils() {} - - /** - * Find a specific method using reflection - * - * @param managedType Class object to find method in - * @param prefix Method name prefix used when finding the method. Case does not matter. - * @param paramTypes List of input argument types - * @param retType Return type - * - * @return Found method or Optional.absent() if there's no such method - */ - @Nonnull - public static Optional findMethodReflex(@Nonnull final Class managedType, - @Nonnull final String prefix, - @Nonnull final List> paramTypes, - @Nonnull final Class retType) { - for (Method method : managedType.getMethods()) { - if(isMethodMatch(prefix, paramTypes, retType, method)) { - return Optional.of(method); - } - } - - return Optional.absent(); - } - - private static boolean isMethodMatch(final @Nonnull String prefix, - final @Nonnull List> paramTypes, - final @Nonnull Class retType, final Method method) { - if (!method.getName().toLowerCase().startsWith(prefix.toLowerCase())) { - return false; - } - - final Class[] parameterTypes = method.getParameterTypes(); - if (parameterTypes.length != paramTypes.size()) { - return false; - } - - for (int i = 0; i < parameterTypes.length; i++) { - if (!parameterTypes[i].isAssignableFrom(paramTypes.get(i))) { - return false; - } - } - - if (!method.getReturnType().equals(retType)) { - return false; - } - - return true; - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java index ddef7a94c..6eb7ef576 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java @@ -19,6 +19,7 @@ package io.fd.honeycomb.v3po.impl.trans.r.util; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ChildVppReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.util.ReflectionUtils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java deleted file mode 100644 index ddf789c16..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.r.util; - -import com.google.common.annotations.Beta; - -/** - * Abstract utility to hold the vppApi reference. - */ -@Beta -public abstract class VppApiReaderCustomizer { - - private final org.openvpp.vppjapi.vppApi vppApi; - - protected VppApiReaderCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { - this.vppApi = vppApi; - } - - /** - * Get vppApi reference - * - * @return vppApi reference - */ - public org.openvpp.vppjapi.vppApi getVppApi() { - return vppApi; - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java deleted file mode 100644 index 3a765d796..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.r.util; - -import com.google.common.base.Function; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.r.SubtreeManager; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.binding.ChildOf; -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; - -public final class VppRWUtils { - - private VppRWUtils() {} - - /** - * Find next item in ID after provided type - */ - @Nonnull - public static InstanceIdentifier.PathArgument getNextId(@Nonnull final InstanceIdentifier id, - @Nonnull final InstanceIdentifier type) { - // TODO this is inefficient(maybe, depending on actual Iterable type) - final Iterable pathArguments = id.getPathArguments(); - final int i = Iterables.indexOf(pathArguments, new Predicate() { - @Override - public boolean apply(final InstanceIdentifier.PathArgument input) { - return input.getType().isAssignableFrom(type.getTargetType()); - } - }); - Preconditions.checkArgument(i >= 0, "Unable to find %s type in %s", type.getTargetType(), id); - return Iterables.get(pathArguments, i + 1); - } - - public static List>> emptyChildReaderList() { - return Collections.emptyList(); - } - - public static List>> emptyAugReaderList() { - return Collections.emptyList(); - } - - public static List>> singletonAugReaderList( - ChildVppReader> item) { - return Collections.>>singletonList(item); - } - - public static List>> singletonChildReaderList( - ChildVppReader> item) { - return Collections.>>singletonList(item); - } - - /** - * Replace last item in ID with a provided IdentifiableItem of the same type - */ - @SuppressWarnings("unchecked") - @Nonnull - public static , K extends Identifier> InstanceIdentifier replaceLastInId( - @Nonnull final InstanceIdentifier id, final InstanceIdentifier.IdentifiableItem currentBdItem) { - - final Iterable pathArguments = id.getPathArguments(); - final Iterable withoutCurrent = - Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1); - final Iterable concat = - Iterables.concat(withoutCurrent, Collections.singleton(currentBdItem)); - return (InstanceIdentifier) InstanceIdentifier.create(concat); - } - - /** - * Create IdentifiableItem from target type of provided ID with provided key - */ - @Nonnull - public static , K extends Identifier> InstanceIdentifier.IdentifiableItem getCurrentIdItem( - @Nonnull final InstanceIdentifier id, final K key) { - return new InstanceIdentifier.IdentifiableItem<>(id.getTargetType(), key); - } - - /** - * Trim InstanceIdentifier at indexOf(type) - */ - @SuppressWarnings("unchecked") - @Nonnull - public static InstanceIdentifier cutId(@Nonnull final InstanceIdentifier id, - @Nonnull final InstanceIdentifier type) { - final Iterable pathArguments = id.getPathArguments(); - final int i = Iterables.indexOf(pathArguments, new Predicate() { - @Override - public boolean apply(final InstanceIdentifier.PathArgument input) { - return input.getType().equals(type.getTargetType()); - } - }); - Preconditions.checkArgument(i >= 0, "ID %s does not contain %s", id, type); - return (InstanceIdentifier) InstanceIdentifier.create(Iterables.limit(pathArguments, i + 1)); - } - - /** - * Create a map from a collection, checking for duplicity in the process - */ - @Nonnull - public static Map uniqueLinkedIndex(@Nonnull final Collection values, @Nonnull final Function keyFunction) { - final Map objectObjectLinkedHashMap = Maps.newLinkedHashMap(); - for (V value : values) { - final K key = keyFunction.apply(value); - Preconditions.checkArgument(objectObjectLinkedHashMap.put(key, value) == null, - "Duplicate key detected : %s", key); - } - return objectObjectLinkedHashMap; - } - - public static final Function, Class> - MANAGER_CLASS_FUNCTION = new Function, Class>() { - @Override - public Class apply(final SubtreeManager input) { - return input.getManagedDataObjectType().getTargetType(); - } - }; - - public static final Function>, Class> - MANAGER_CLASS_AUG_FUNCTION = new Function>, Class>() { - - @Override - @SuppressWarnings("unchecked") - public Class apply(final SubtreeManager> input) { - final Class> targetType = input.getManagedDataObjectType().getTargetType(); - Preconditions.checkArgument(DataObject.class.isAssignableFrom(targetType)); - return (Class) targetType; - } - }; - - @SuppressWarnings("unchecked") - public static InstanceIdentifier appendTypeToId( - final InstanceIdentifier parentId, final InstanceIdentifier type) { - Preconditions.checkArgument(!parentId.contains(type), - "Unexpected InstanceIdentifier %s, already contains %s", parentId, type); - final InstanceIdentifier.PathArgument t = Iterables.getOnlyElement(type.getPathArguments()); - return (InstanceIdentifier) InstanceIdentifier.create(Iterables.concat( - parentId.getPathArguments(), Collections.singleton(t))); - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java new file mode 100644 index 000000000..6602d750d --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.impl.trans.util; + +import com.google.common.base.Optional; +import java.lang.reflect.Method; +import java.util.List; +import javax.annotation.Nonnull; + +/** + * Reflection based utilities + */ +public final class ReflectionUtils { + + private ReflectionUtils() {} + + /** + * Find a specific method using reflection + * + * @param managedType Class object to find method in + * @param prefix Method name prefix used when finding the method. Case does not matter. + * @param paramTypes List of input argument types + * @param retType Return type + * + * @return Found method or Optional.absent() if there's no such method + */ + @Nonnull + public static Optional findMethodReflex(@Nonnull final Class managedType, + @Nonnull final String prefix, + @Nonnull final List> paramTypes, + @Nonnull final Class retType) { + for (Method method : managedType.getMethods()) { + if(isMethodMatch(prefix, paramTypes, retType, method)) { + return Optional.of(method); + } + } + + return Optional.absent(); + } + + private static boolean isMethodMatch(final @Nonnull String prefix, + final @Nonnull List> paramTypes, + final @Nonnull Class retType, final Method method) { + if (!method.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + return false; + } + + final Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length != paramTypes.size()) { + return false; + } + + for (int i = 0; i < parameterTypes.length; i++) { + if (!parameterTypes[i].isAssignableFrom(paramTypes.get(i))) { + return false; + } + } + + if (!method.getReturnType().equals(retType)) { + return false; + } + + return true; + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiCustomizer.java new file mode 100644 index 000000000..f33dd988e --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiCustomizer.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.impl.trans.util; + +import com.google.common.annotations.Beta; + +/** + * Abstract utility to hold the vppApi reference. + */ +@Beta +public abstract class VppApiCustomizer { + + private final org.openvpp.vppjapi.vppApi vppApi; + + protected VppApiCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { + this.vppApi = vppApi; + } + + /** + * Get vppApi reference + * + * @return vppApi reference + */ + public org.openvpp.vppjapi.vppApi getVppApi() { + return vppApi; + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java new file mode 100644 index 000000000..fe0f1f2fb --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.impl.trans.util; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import io.fd.honeycomb.v3po.impl.trans.SubtreeManager; +import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; +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; + +public final class VppRWUtils { + + private VppRWUtils() {} + + /** + * Find next item in ID after provided type + */ + @Nonnull + public static InstanceIdentifier.PathArgument getNextId(@Nonnull final InstanceIdentifier id, + @Nonnull final InstanceIdentifier type) { + // TODO this is inefficient(maybe, depending on actual Iterable type) + final Iterable pathArguments = id.getPathArguments(); + final int i = Iterables.indexOf(pathArguments, new Predicate() { + @Override + public boolean apply(final InstanceIdentifier.PathArgument input) { + return input.getType().isAssignableFrom(type.getTargetType()); + } + }); + Preconditions.checkArgument(i >= 0, "Unable to find %s type in %s", type.getTargetType(), id); + return Iterables.get(pathArguments, i + 1); + } + + public static List>> emptyChildReaderList() { + return Collections.emptyList(); + } + + public static List>> emptyAugReaderList() { + return Collections.emptyList(); + } + + public static List>> singletonAugReaderList( + ChildVppReader> item) { + return Collections.>>singletonList(item); + } + + public static List>> singletonChildReaderList( + ChildVppReader> item) { + return Collections.>>singletonList(item); + } + + /** + * Replace last item in ID with a provided IdentifiableItem of the same type + */ + @SuppressWarnings("unchecked") + @Nonnull + public static , K extends Identifier> InstanceIdentifier replaceLastInId( + @Nonnull final InstanceIdentifier id, final InstanceIdentifier.IdentifiableItem currentBdItem) { + + final Iterable pathArguments = id.getPathArguments(); + final Iterable withoutCurrent = + Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1); + final Iterable concat = + Iterables.concat(withoutCurrent, Collections.singleton(currentBdItem)); + return (InstanceIdentifier) InstanceIdentifier.create(concat); + } + + /** + * Create IdentifiableItem from target type of provided ID with provided key + */ + @Nonnull + public static , K extends Identifier> InstanceIdentifier.IdentifiableItem getCurrentIdItem( + @Nonnull final InstanceIdentifier id, final K key) { + return new InstanceIdentifier.IdentifiableItem<>(id.getTargetType(), key); + } + + /** + * Trim InstanceIdentifier at indexOf(type) + */ + @SuppressWarnings("unchecked") + @Nonnull + public static InstanceIdentifier cutId(@Nonnull final InstanceIdentifier id, + @Nonnull final InstanceIdentifier type) { + final Iterable pathArguments = id.getPathArguments(); + final int i = Iterables.indexOf(pathArguments, new Predicate() { + @Override + public boolean apply(final InstanceIdentifier.PathArgument input) { + return input.getType().equals(type.getTargetType()); + } + }); + Preconditions.checkArgument(i >= 0, "ID %s does not contain %s", id, type); + return (InstanceIdentifier) InstanceIdentifier.create(Iterables.limit(pathArguments, i + 1)); + } + + /** + * Create a map from a collection, checking for duplicity in the process + */ + @Nonnull + public static Map uniqueLinkedIndex(@Nonnull final Collection values, @Nonnull final Function keyFunction) { + final Map objectObjectLinkedHashMap = Maps.newLinkedHashMap(); + for (V value : values) { + final K key = keyFunction.apply(value); + Preconditions.checkArgument(objectObjectLinkedHashMap.put(key, value) == null, + "Duplicate key detected : %s", key); + } + return objectObjectLinkedHashMap; + } + + public static final Function, Class> + MANAGER_CLASS_FUNCTION = new Function, Class>() { + @Override + public Class apply(final SubtreeManager input) { + return input.getManagedDataObjectType().getTargetType(); + } + }; + + public static final Function>, Class> + MANAGER_CLASS_AUG_FUNCTION = new Function>, Class>() { + + @Override + @SuppressWarnings("unchecked") + public Class apply(final SubtreeManager> input) { + final Class> targetType = input.getManagedDataObjectType().getTargetType(); + Preconditions.checkArgument(DataObject.class.isAssignableFrom(targetType)); + return (Class) targetType; + } + }; + + @SuppressWarnings("unchecked") + public static InstanceIdentifier appendTypeToId( + final InstanceIdentifier parentId, final InstanceIdentifier type) { + Preconditions.checkArgument(!parentId.contains(type), + "Unexpected InstanceIdentifier %s, already contains %s", parentId, type); + final InstanceIdentifier.PathArgument t = Iterables.getOnlyElement(type.getPathArguments()); + return (InstanceIdentifier) InstanceIdentifier.create(Iterables.concat( + parentId.getPathArguments(), Collections.singleton(t))); + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java index 041d9eb55..1930a83e5 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java @@ -18,8 +18,8 @@ package io.fd.honeycomb.v3po.impl.vppstate; import com.google.common.collect.Lists; import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ListVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppApiReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import io.fd.honeycomb.v3po.impl.trans.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; @@ -40,7 +40,7 @@ import org.openvpp.vppjapi.vppBridgeDomainDetails; import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails; import org.openvpp.vppjapi.vppL2Fib; -public final class BridgeDomainCustomizer extends VppApiReaderCustomizer +public final class BridgeDomainCustomizer extends VppApiCustomizer implements ListVppReaderCustomizer { public BridgeDomainCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) { diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java index de596994d..d56c4e5a9 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java @@ -17,7 +17,7 @@ package io.fd.honeycomb.v3po.impl.vppstate; import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ChildVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppApiReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.util.VppApiCustomizer; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; @@ -28,7 +28,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.vppjapi.vppVersion; public final class VersionCustomizer - extends VppApiReaderCustomizer + extends VppApiCustomizer implements ChildVppReaderCustomizer { public VersionCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) { diff --git a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java deleted file mode 100644 index f50a70a69..000000000 --- a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.vppstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyString; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import io.fd.honeycomb.v3po.impl.trans.r.VppReader; -import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeRootVppReader; -import io.fd.honeycomb.v3po.impl.trans.r.util.DelegatingReaderRegistry; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.vppjapi.vppApi; -import org.openvpp.vppjapi.vppBridgeDomainDetails; -import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails; -import org.openvpp.vppjapi.vppL2Fib; -import org.openvpp.vppjapi.vppVersion; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") -@PrepareForTest(vppApi.class) -public class BdTest { - - public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33"); - - private vppApi api; - private CompositeRootVppReader vppStateReader; - private DelegatingReaderRegistry readerRegistry; - private vppBridgeDomainDetails bdDetails; - private vppBridgeDomainDetails bdDetails2; - - @Before - public void setUp() throws Exception { - api = PowerMockito.mock(vppApi.class); - - bdDetails = new vppBridgeDomainDetails(); - setIfcs(bdDetails); - setBaseAttrs(bdDetails, "bdn1", 1); - - bdDetails2 = new vppBridgeDomainDetails(); - setIfcs(bdDetails2); - setBaseAttrs(bdDetails2, "bdn2", 2); - - final vppL2Fib[] l2Fibs = getL2Fibs(); - PowerMockito.doReturn(l2Fibs).when(api).l2FibTableDump(Matchers.anyInt()); - PowerMockito.doAnswer(new Answer() { - - @Override - public vppBridgeDomainDetails answer(final InvocationOnMock invocationOnMock) throws Throwable { - final Integer idx = (Integer) invocationOnMock.getArguments()[0]; - switch (idx) { - case 1 : return bdDetails; - case 2 : return bdDetails2; - default: return null; - } - } - }).when(api).getBridgeDomainDetails(Matchers.anyInt()); - - PowerMockito.doAnswer(new Answer() { - @Override - public Object answer(final InvocationOnMock invocationOnMock) throws Throwable { - final String name = (String) invocationOnMock.getArguments()[0]; - switch (name) { - case "bdn1" : return 1; - case "bdn2" : return 2; - default: return null; - } - } - }).when(api).bridgeDomainIdFromName(anyString()); - PowerMockito.doReturn(new int[] {1, 2}).when(api).bridgeDomainDump(Matchers.anyInt()); - PowerMockito.doReturn(VERSION).when(api).getVppVersion(); - vppStateReader = VppStateUtils.getVppStateReader(api); - readerRegistry = new DelegatingReaderRegistry(Collections.>singletonList(vppStateReader)); - } - - private vppL2Fib[] getL2Fibs() { - return new vppL2Fib[] { - new vppL2Fib(new byte[]{1,2,3,4,5,6}, true, "ifc1", true, true), - new vppL2Fib(new byte[]{2,2,3,4,5,6}, true, "ifc2", true, true), - }; - } - - private void setIfcs(final vppBridgeDomainDetails bdDetails) { - final vppBridgeDomainInterfaceDetails ifcDetails = new vppBridgeDomainInterfaceDetails(); - ifcDetails.interfaceName = "ifc"; - ifcDetails.splitHorizonGroup = 2; - bdDetails.interfaces = new vppBridgeDomainInterfaceDetails[] {ifcDetails}; - } - - private void setBaseAttrs(final vppBridgeDomainDetails bdDetails, final String bdn, final int i) { - bdDetails.name = bdn; - bdDetails.arpTerm = true; - bdDetails.bdId = i; - bdDetails.bviInterfaceName = "ifc"; - bdDetails.flood = true; - bdDetails.forward = true; - bdDetails.learn = true; - bdDetails.uuFlood = true; - } - - @Test - public void testReadAll() throws Exception { - final List dataObjects = readerRegistry.readAll(); - assertEquals(dataObjects.size(), 1); - final DataObject dataObject = dataObjects.get(0); - assertTrue(dataObject instanceof VppState); - assertVersion((VppState) dataObject); - assertEquals(2, ((VppState) dataObject).getBridgeDomains().getBridgeDomain().size()); - } - - private void assertVersion(final VppState dataObject) { - assertEquals( - new VersionBuilder() - .setName("test") - .setBuildDirectory("1") - .setBranch("2") - .setBuildDate("33") - .build(), - dataObject.getVersion()); - } - - @Test - public void testReadSpecific() throws Exception { - final List read = readerRegistry.read(InstanceIdentifier.create(VppState.class)); - assertEquals(read.size(), 1); - assertVersion((VppState) read.get(0)); - } - - @Test - public void testReadBridgeDomains() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); - - List read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class)); -// System.err.println(read); - assertEquals(read.size(), 1); - assertEquals(readRoot.getBridgeDomains(), read.get(0)); - } - - /** - * L2fib does not have a dedicated reader, relying on auto filtering - */ - @Test - public void testReadL2Fib() throws Exception { - // Deep child without a dedicated reader with specific l2fib key - List read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")) - .child(L2Fib.class, new L2FibKey(new PhysAddress("01:02:03:04:05:06")))); -// System.err.println(read); - assertEquals(read.size(), 1); - - // non existing l2fib - read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")) - .child(L2Fib.class, new L2FibKey(new PhysAddress("FF:FF:FF:04:05:06")))); -// System.err.println(read); - assertEquals(read.size(), 0); - } - - /** - * L2fib does not have a dedicated reader, relying on auto filtering - */ - @Test - public void testReadL2FibAll() throws Exception { - // Deep child without a dedicated reader - final InstanceIdentifier id = InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2Fib.class); - final List read = readerRegistry.read(id); -// System.err.println(read); - assertEquals(read.toString(), read.size(), 2); - - // test if direct read returns the same value - final List read2 = vppStateReader.read(id); -// System.err.println(read); - assertEquals(read, read2); - } - - @Test - public void testReadBridgeDomainAll() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); - - final List read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class)); -// System.err.println(read); - assertEquals(read.size(), 2); - assertEquals(readRoot.getBridgeDomains().getBridgeDomain(), read); - } - - @Test - public void testReadBridgeDomain() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); - - final List read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1"))); - - assertEquals(read.size(), 1); - assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(), new Predicate() { - @Override - public boolean apply(final BridgeDomain input) { - return input.getKey().getName().equals("bdn1"); - } - }), read.get(0)); - } - - @Ignore("Bridge domain customizer does not check whether the bd exists or not and fails with NPE, add it there") - @Test - public void testReadBridgeDomainNotExisting() throws Exception { - final List read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("NOT EXISTING"))); - assertEquals(read.size(), 0); - } - - @Test - public void testReadVersion() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); - - List read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class)); -// System.err.println(read); - assertEquals(read.size(), 1); - assertEquals(readRoot.getVersion(), read.get(0)); - } -} \ No newline at end of file diff --git a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateTest.java b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateTest.java new file mode 100644 index 000000000..66831c77a --- /dev/null +++ b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateTest.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.impl.vppstate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import io.fd.honeycomb.v3po.impl.trans.r.VppReader; +import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeRootVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.util.DelegatingReaderRegistry; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppApi; +import org.openvpp.vppjapi.vppBridgeDomainDetails; +import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails; +import org.openvpp.vppjapi.vppL2Fib; +import org.openvpp.vppjapi.vppVersion; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") +@PrepareForTest(vppApi.class) +public class VppStateTest { + + public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33"); + + private vppApi api; + private CompositeRootVppReader vppStateReader; + private DelegatingReaderRegistry readerRegistry; + private vppBridgeDomainDetails bdDetails; + private vppBridgeDomainDetails bdDetails2; + + @Before + public void setUp() throws Exception { + api = PowerMockito.mock(vppApi.class); + + bdDetails = new vppBridgeDomainDetails(); + setIfcs(bdDetails); + setBaseAttrs(bdDetails, "bdn1", 1); + + bdDetails2 = new vppBridgeDomainDetails(); + setIfcs(bdDetails2); + setBaseAttrs(bdDetails2, "bdn2", 2); + + final vppL2Fib[] l2Fibs = getL2Fibs(); + PowerMockito.doReturn(l2Fibs).when(api).l2FibTableDump(Matchers.anyInt()); + PowerMockito.doAnswer(new Answer() { + + @Override + public vppBridgeDomainDetails answer(final InvocationOnMock invocationOnMock) throws Throwable { + final Integer idx = (Integer) invocationOnMock.getArguments()[0]; + switch (idx) { + case 1 : return bdDetails; + case 2 : return bdDetails2; + default: return null; + } + } + }).when(api).getBridgeDomainDetails(Matchers.anyInt()); + + PowerMockito.doAnswer(new Answer() { + @Override + public Object answer(final InvocationOnMock invocationOnMock) throws Throwable { + final String name = (String) invocationOnMock.getArguments()[0]; + switch (name) { + case "bdn1" : return 1; + case "bdn2" : return 2; + default: return null; + } + } + }).when(api).bridgeDomainIdFromName(anyString()); + PowerMockito.doReturn(new int[] {1, 2}).when(api).bridgeDomainDump(Matchers.anyInt()); + PowerMockito.doReturn(VERSION).when(api).getVppVersion(); + vppStateReader = VppStateUtils.getVppStateReader(api); + readerRegistry = new DelegatingReaderRegistry(Collections.>singletonList(vppStateReader)); + } + + private vppL2Fib[] getL2Fibs() { + return new vppL2Fib[] { + new vppL2Fib(new byte[]{1,2,3,4,5,6}, true, "ifc1", true, true), + new vppL2Fib(new byte[]{2,2,3,4,5,6}, true, "ifc2", true, true), + }; + } + + private void setIfcs(final vppBridgeDomainDetails bdDetails) { + final vppBridgeDomainInterfaceDetails ifcDetails = new vppBridgeDomainInterfaceDetails(); + ifcDetails.interfaceName = "ifc"; + ifcDetails.splitHorizonGroup = 2; + bdDetails.interfaces = new vppBridgeDomainInterfaceDetails[] {ifcDetails}; + } + + private void setBaseAttrs(final vppBridgeDomainDetails bdDetails, final String bdn, final int i) { + bdDetails.name = bdn; + bdDetails.arpTerm = true; + bdDetails.bdId = i; + bdDetails.bviInterfaceName = "ifc"; + bdDetails.flood = true; + bdDetails.forward = true; + bdDetails.learn = true; + bdDetails.uuFlood = true; + } + + @Test + public void testReadAll() throws Exception { + final List dataObjects = readerRegistry.readAll(); + assertEquals(dataObjects.size(), 1); + final DataObject dataObject = dataObjects.get(0); + assertTrue(dataObject instanceof VppState); + assertVersion((VppState) dataObject); + assertEquals(2, ((VppState) dataObject).getBridgeDomains().getBridgeDomain().size()); + } + + private void assertVersion(final VppState dataObject) { + assertEquals( + new VersionBuilder() + .setName("test") + .setBuildDirectory("1") + .setBranch("2") + .setBuildDate("33") + .build(), + dataObject.getVersion()); + } + + @Test + public void testReadSpecific() throws Exception { + final List read = readerRegistry.read(InstanceIdentifier.create(VppState.class)); + assertEquals(read.size(), 1); + assertVersion((VppState) read.get(0)); + } + + @Test + public void testReadBridgeDomains() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); + + List read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class)); +// System.err.println(read); + assertEquals(read.size(), 1); + assertEquals(readRoot.getBridgeDomains(), read.get(0)); + } + + /** + * L2fib does not have a dedicated reader, relying on auto filtering + */ + @Test + public void testReadL2Fib() throws Exception { + // Deep child without a dedicated reader with specific l2fib key + List read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")) + .child(L2Fib.class, new L2FibKey(new PhysAddress("01:02:03:04:05:06")))); +// System.err.println(read); + assertEquals(read.size(), 1); + + // non existing l2fib + read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")) + .child(L2Fib.class, new L2FibKey(new PhysAddress("FF:FF:FF:04:05:06")))); +// System.err.println(read); + assertEquals(read.size(), 0); + } + + /** + * L2fib does not have a dedicated reader, relying on auto filtering + */ + @Test + public void testReadL2FibAll() throws Exception { + // Deep child without a dedicated reader + final InstanceIdentifier id = InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")).child(L2Fib.class); + final List read = readerRegistry.read(id); +// System.err.println(read); + assertEquals(read.toString(), read.size(), 2); + + // test if direct read returns the same value + final List read2 = vppStateReader.read(id); +// System.err.println(read); + assertEquals(read, read2); + } + + @Test + public void testReadBridgeDomainAll() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); + + final List read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class)); +// System.err.println(read); + assertEquals(read.size(), 2); + assertEquals(readRoot.getBridgeDomains().getBridgeDomain(), read); + } + + @Test + public void testReadBridgeDomain() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); + + final List read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1"))); + + assertEquals(read.size(), 1); + assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(), new Predicate() { + @Override + public boolean apply(final BridgeDomain input) { + return input.getKey().getName().equals("bdn1"); + } + }), read.get(0)); + } + + @Ignore("Bridge domain customizer does not check whether the bd exists or not and fails with NPE, add it there") + @Test + public void testReadBridgeDomainNotExisting() throws Exception { + final List read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("NOT EXISTING"))); + assertEquals(read.size(), 0); + } + + @Test + public void testReadVersion() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class)).get(0); + + List read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class)); +// System.err.println(read); + assertEquals(read.size(), 1); + assertEquals(readRoot.getVersion(), read.get(0)); + } +} \ No newline at end of file diff --git a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java index f32a45379..e700d2e1f 100644 --- a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java +++ b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java @@ -22,7 +22,7 @@ import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeListVppReader; import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeRootVppReader; import io.fd.honeycomb.v3po.impl.trans.r.util.ReflexiveChildReaderCustomizer; import io.fd.honeycomb.v3po.impl.trans.r.util.ReflexiveRootReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; -- cgit 1.2.3-korg