diff options
126 files changed, 4459 insertions, 1337 deletions
diff --git a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelper.java b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelper.java index 17817fe1d..88d016606 100644 --- a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelper.java +++ b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelper.java @@ -2,13 +2,121 @@ package org.onap.ccsdk.features.lib.rlock; import java.util.Collection; +/** + * <p> + * A cooperative locking service. This service can be used to synchronize access to shared + * resources, so only one thread has access to it at any time. It is <i>cooperative</i> locking, + * meaning the threads have to agree to explicitly lock the resource, whenever they need to access + * it and then explicitly unlock it, when they are done with the resource. While a resource is + * locked by a thread, no other thread can lock it, until it is unlocked. + * </p> + * <p> + * The term <tt><b>resource</b></tt> represents anything that needs a synchronized access, for + * example, message queue or connection pool or limited bandwidth capacity. + * </p> + * <p> + * The implementation here provides a <i>distributed</i> locking functionality, which means threads + * can reside in the same application instance or different application instances, on same or + * different machines (see {@link LockHelperImpl}). + * </p> + * <p> + * Example: Bandwidth check: + * </p> + * <pre style="color:darkblue;"> + * boolean success = false; + * String resourceName = "Port-123-Bandwidth"; + * int neededBandwidth = 100; // 100 Mbps + * int bandwidthLimit = 1000; + * int lockRequester = "this-thread-id-" + (int) (Math.random() * 1000000); + * int lockTimeout = 30; // 30 sec - the longest time, we expect to complete the check + * + * try { + * lockHelper.lock(resourceName, lockRequester, lockTimeout); + * + * int usedBandwidth = portBandwidthDao.readUsedBandwidth("Port-123"); + * if (usedBandwidth + neededBandwidth <= bandwidthLimit) { + * portBandwidthDao.updateUsedBandwidth("Port-123", usedBandwidth + neededBandwidth); + * success = true; + * } + * } finally { + * lockHelper.unlock(resourceName, true); + * } + * </pre> + * + * @see SynchronizedFunction + * @see LockHelperImpl + * @see ResourceLockedException + */ public interface LockHelper { - void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */); + /** + * <p> + * Locks the specified resource. Lock requester identifies the thread that is requesting the lock. + * If the resource is already locked by another lock requester (another thread), then the thread is + * blocked until the resource is available. If the resource is available or locked by the same + * thread, the lock succeeds.<br/> + * Usually lock requester can be generated using the thread name and some random number. + * </p> + * <p> + * Lock timeout specifies how long (in seconds) to keep the lock in case the thread misses to unlock + * the resource. The lock will expire after this time in case the resource is never unlocked. This + * time should be set to the maximum time expected for the processing of the resource, so the lock + * does not expire until the thread is done with the resource. The lock timeout is supposed to avoid + * permanently locking a resource in case of application crash in the middle of processing. + * </p> + * + * @param resourceName Identifies the resource to be locked + * @param lockRequester Identifies the thread requesting the lock + * @param lockTimeout The expiration timeout of the lock (in seconds) + * @throws ResourceLockedException if the resource cannot be locked + */ + void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */); - void unlock(String resourceName, boolean force); + /** + * <p> + * Unlocks the specified resource. This method should always succeed including in the case, when the + * resource is already unlocked. + * </p> + * <p> + * Force parameter can be used in case the same thread might lock the same resource multiple times. + * In case resource is locked multiple times, normally, in case force parameter is false, the thread + * will need to unlock the resource the same number of times for the resource to become available + * again. If the force parameter is true, then the resource will be unlocked immediately, no matter + * how many times it has been locked. + * </p> + * + * @param resourceName Identifies the resource to be unlocked + * @param force If true, forces resource to be unlocked immediately, even if it has been locked more + * than once + */ + void unlock(String resourceName, boolean force); - void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */); + /** + * <p> + * Locks multiple resources at once. It ensures that either all resources are successfully locked or + * none is. + * </p> + * + * @param resourceNameList The set of resources to lock + * @param lockRequester Identifies the thread requesting the lock + * @param lockTimeout The expiration timeout of the lock (in seconds) + * @throws ResourceLockedException if any of the resources cannot be locked + * + * @see LockHelper#lock(String, String, int) + */ + void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */); - void unlock(Collection<String> resourceNameList, boolean force); + /** + * <p> + * Unlocks the specified set of resources. This method should always succeed including in the case, + * when any of the resources are already unlocked. + * </p> + * + * @param resourceNameList The set of resources to unlock + * @param force If true, forces all resources to be unlocked immediately, even if any of them have + * been locked more than once + * + * @see LockHelper#unlock(String, boolean) + */ + void unlock(Collection<String> resourceNameList, boolean force); } diff --git a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelperImpl.java b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelperImpl.java index 666fb6af5..63fe111df 100644 --- a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelperImpl.java +++ b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/LockHelperImpl.java @@ -5,169 +5,211 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; - import javax.sql.DataSource; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * <p> + * Implementation of the locking service, providing <i>distributed</i> locking functionality. It is + * done using a table in SQL Database as a single synchronization point. Hence, for this + * implementation, it is required that all participating threads in all participating applications + * access the same database instance (or a distributed database that looks like one database + * instance). + * </p> + * <p> + * The following table is required in the database: + * </p> + * + * <pre style="color:darkblue;"> + * CREATE TABLE IF NOT EXISTS `resource_lock` ( + * `resource_lock_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + * `resource_name` varchar(256), + * `lock_holder` varchar(100) NOT NULL, + * `lock_count` smallint(6) NOT NULL, + * `lock_time` datetime NOT NULL, + * `expiration_time` datetime NOT NULL, + * PRIMARY KEY (`resource_lock_id`), + * UNIQUE KEY `IX1_RESOURCE_LOCK` (`resource_name`) + * ); + * </pre> + * <p> + * The implementation tries to insert records in the table for all the requested resources. If there + * are already records for any of the resources, it fails and then makes several more tries before + * giving up and throwing {@link ResourceLockedException}. + * </p> + * <p> + * The class has 2 configurable parameters: + * <ul> + * <li><tt><b>retryCount</b></tt>: the numbers of retries, when locking a resource, default 20</li> + * <li><tt><b>lockWait</b></tt>: the time between each retry (in seconds), default 5 seconds</li> + * </ul> + * The total time before locking fails would be <tt>retryCount * lockWait</tt> seconds. + * </p> + * + * @see LockHelper + * @see SynchronizedFunction + * @see ResourceLockedException + */ public class LockHelperImpl implements LockHelper { - private static final Logger log = LoggerFactory.getLogger(LockHelperImpl.class); + private static final Logger log = LoggerFactory.getLogger(LockHelperImpl.class); - private int retryCount = 20; - private int lockWait = 5; // Seconds + private int retryCount = 20; + private int lockWait = 5; // Seconds - private DataSource dataSource; + private DataSource dataSource; - @Override - public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */) { - lock(Collections.singleton(resourceName), lockRequester, lockTimeout); - } + @Override + public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */) { + lock(Collections.singleton(resourceName), lockRequester, lockTimeout); + } - @Override - public void unlock(String resourceName, boolean force) { - unlock(Collections.singleton(resourceName), force); - } + @Override + public void unlock(String resourceName, boolean force) { + unlock(Collections.singleton(resourceName), force); + } - @Override - public void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { - for (int i = 0; true; i++) { - try { - tryLock(resourceNameList, lockRequester, lockTimeout); + @Override + public void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { + for (int i = 0; true; i++) { + try { + tryLock(resourceNameList, lockRequester, lockTimeout); log.info("Resources locked: " + resourceNameList); - return; - } catch (ResourceLockedException e) { - if (i > retryCount) { - throw e; - } - try { - Thread.sleep(lockWait * 1000L); - } catch (InterruptedException ex) { - } - } - } - } - - @Override - public void unlock(Collection<String> lockNames, boolean force) { - if (lockNames == null || lockNames.size() == 0) { - return; - } - - try (ResourceLockDao resourceLockDao = new ResourceLockDao(dataSource)) { - try { - for (String name : lockNames) { - ResourceLock l = resourceLockDao.getByResourceName(name); - if (l != null) { - if (force || l.lockCount == 1) { - resourceLockDao.delete(l.id); - } else { - resourceLockDao.decrementLockCount(l.id); - } - } - } - resourceLockDao.commit(); - log.info("Resources unlocked: " + lockNames); - } catch (Exception e) { - resourceLockDao.rollback(); - } - } - } - - public void tryLock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { - if (resourceNameList == null || resourceNameList.isEmpty()) { - return; - } - - lockRequester = generateLockRequester(lockRequester, 100); - - // First check if all requested records are available to lock - - Date now = new Date(); - - try (ResourceLockDao resourceLockDao = new ResourceLockDao(dataSource)) { - try { - List<ResourceLock> dbLockList = new ArrayList<>(); - List<String> insertLockNameList = new ArrayList<>(); - for (String name : resourceNameList) { - ResourceLock l = resourceLockDao.getByResourceName(name); - - boolean canLock = l == null || now.getTime() > l.expirationTime.getTime() || lockRequester != null && lockRequester.equals(l.lockHolder) || l.lockCount <= 0; - if (!canLock) { - throw new ResourceLockedException(l.resourceName, l.lockHolder, lockRequester); - } - - if (l != null) { - if (now.getTime() > l.expirationTime.getTime() || l.lockCount <= 0) { - l.lockCount = 0; - } - dbLockList.add(l); - } else { - insertLockNameList.add(name); - } - } - - // Update the lock info in DB - for (ResourceLock l : dbLockList) { - resourceLockDao.update(l.id, lockRequester, now, new Date(now.getTime() + lockTimeout * 1000), l.lockCount + 1); - } - - // Insert records for those that are not yet there - for (String lockName : insertLockNameList) { - ResourceLock l = new ResourceLock(); - l.resourceName = lockName; - l.lockHolder = lockRequester; - l.lockTime = now; - l.expirationTime = new Date(now.getTime() + lockTimeout * 1000); - l.lockCount = 1; - - try { - resourceLockDao.add(l); - } catch (Exception e) { - throw new ResourceLockedException(l.resourceName, "unknown", lockRequester); - } - } - - resourceLockDao.commit(); - - } catch (Exception e) { - resourceLockDao.rollback(); - throw e; - } - } - } - - private static String generateLockRequester(String name, int maxLength) { - if (name == null) { - name = ""; - } - int l1 = name.length(); - String tname = Thread.currentThread().getName(); - int l2 = tname.length(); - if (l1 + l2 + 1 > maxLength) { - int maxl1 = maxLength / 2; - if (l1 > maxl1) { - name = name.substring(0, maxl1); - l1 = maxl1; - } - int maxl2 = maxLength - l1 - 1; - if (l2 > maxl2) { - tname = tname.substring(0, 6) + "..." + tname.substring(l2 - maxl2 + 9); - } - } - return tname + '-' + name; - } - - public void setRetryCount(int retryCount) { - this.retryCount = retryCount; - } - - public void setLockWait(int lockWait) { - this.lockWait = lockWait; - } - - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } + return; + } catch (ResourceLockedException e) { + if (i > retryCount) { + throw e; + } + try { + Thread.sleep(lockWait * 1000L); + } catch (InterruptedException ex) { + } + } + } + } + + @Override + public void unlock(Collection<String> lockNames, boolean force) { + if (lockNames == null || lockNames.size() == 0) { + return; + } + + try (ResourceLockDao resourceLockDao = new ResourceLockDao(dataSource)) { + try { + for (String name : lockNames) { + ResourceLock l = resourceLockDao.getByResourceName(name); + if (l != null) { + if (force || l.lockCount == 1) { + resourceLockDao.delete(l.id); + } else { + resourceLockDao.decrementLockCount(l.id); + } + } + } + resourceLockDao.commit(); + log.info("Resources unlocked: " + lockNames); + } catch (Exception e) { + resourceLockDao.rollback(); + } + } + } + + public void tryLock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { + if (resourceNameList == null || resourceNameList.isEmpty()) { + return; + } + + lockRequester = generateLockRequester(lockRequester, 100); + + // First check if all requested records are available to lock + + Date now = new Date(); + + try (ResourceLockDao resourceLockDao = new ResourceLockDao(dataSource)) { + try { + List<ResourceLock> dbLockList = new ArrayList<>(); + List<String> insertLockNameList = new ArrayList<>(); + for (String name : resourceNameList) { + ResourceLock l = resourceLockDao.getByResourceName(name); + + boolean canLock = l == null || now.getTime() > l.expirationTime.getTime() + || lockRequester != null && lockRequester.equals(l.lockHolder) || l.lockCount <= 0; + if (!canLock) { + throw new ResourceLockedException(l.resourceName, l.lockHolder, lockRequester); + } + + if (l != null) { + if (now.getTime() > l.expirationTime.getTime() || l.lockCount <= 0) { + l.lockCount = 0; + } + dbLockList.add(l); + } else { + insertLockNameList.add(name); + } + } + + // Update the lock info in DB + for (ResourceLock l : dbLockList) { + resourceLockDao.update(l.id, lockRequester, now, new Date(now.getTime() + lockTimeout * 1000), + l.lockCount + 1); + } + + // Insert records for those that are not yet there + for (String lockName : insertLockNameList) { + ResourceLock l = new ResourceLock(); + l.resourceName = lockName; + l.lockHolder = lockRequester; + l.lockTime = now; + l.expirationTime = new Date(now.getTime() + lockTimeout * 1000); + l.lockCount = 1; + + try { + resourceLockDao.add(l); + } catch (Exception e) { + throw new ResourceLockedException(l.resourceName, "unknown", lockRequester); + } + } + + resourceLockDao.commit(); + + } catch (Exception e) { + resourceLockDao.rollback(); + throw e; + } + } + } + + private static String generateLockRequester(String name, int maxLength) { + if (name == null) { + name = ""; + } + int l1 = name.length(); + String tname = Thread.currentThread().getName(); + int l2 = tname.length(); + if (l1 + l2 + 1 > maxLength) { + int maxl1 = maxLength / 2; + if (l1 > maxl1) { + name = name.substring(0, maxl1); + l1 = maxl1; + } + int maxl2 = maxLength - l1 - 1; + if (l2 > maxl2) { + tname = tname.substring(0, 6) + "..." + tname.substring(l2 - maxl2 + 9); + } + } + return tname + '-' + name; + } + + public void setRetryCount(int retryCount) { + this.retryCount = retryCount; + } + + public void setLockWait(int lockWait) { + this.lockWait = lockWait; + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } } diff --git a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLock.java b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLock.java index a7e966855..a51523859 100644 --- a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLock.java +++ b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLock.java @@ -4,10 +4,10 @@ import java.util.Date; public class ResourceLock { - public long id; - public String resourceName; - public String lockHolder; - public int lockCount; - public Date lockTime; - public Date expirationTime; + public long id; + public String resourceName; + public String lockHolder; + public int lockCount; + public Date lockTime; + public Date expirationTime; } diff --git a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockDao.java b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockDao.java index 4833bb28e..23328577a 100644 --- a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockDao.java +++ b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockDao.java @@ -6,117 +6,119 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; - import javax.sql.DataSource; public class ResourceLockDao implements AutoCloseable { - private Connection con; - - public ResourceLockDao(DataSource dataSource) { - try { - con = dataSource.getConnection(); - con.setAutoCommit(false); - } catch (SQLException e) { - throw new RuntimeException("Error getting DB connection: " + e.getMessage(), e); - } - } - - public void add(ResourceLock l) { - String sql = "INSERT INTO RESOURCE_LOCK (resource_name, lock_holder, lock_count, lock_time, expiration_time)\n" + "VALUES (?, ?, ?, ?, ?)"; - - try (PreparedStatement ps = con.prepareStatement(sql)) { - ps.setString(1, l.resourceName); - ps.setString(2, l.lockHolder); - ps.setInt(3, l.lockCount); - ps.setTimestamp(4, new Timestamp(l.lockTime.getTime())); - ps.setTimestamp(5, new Timestamp(l.expirationTime.getTime())); - ps.execute(); - } catch (SQLException e) { - throw new RuntimeException("Error adding lock to DB: " + e.getMessage(), e); - } - } - - public void update(long id, String lockHolder, Date lockTime, Date expirationTime, int lockCount) { - String sql = "UPDATE RESOURCE_LOCK SET lock_holder = ?, lock_time = ?, expiration_time = ?, lock_count = ? WHERE resource_lock_id = ?"; - - try (PreparedStatement ps = con.prepareStatement(sql)) { - ps.setString(1, lockHolder); - ps.setTimestamp(2, new Timestamp(lockTime.getTime())); - ps.setTimestamp(3, new Timestamp(expirationTime.getTime())); - ps.setInt(4, lockCount); - ps.setLong(5, id); - ps.execute(); - } catch (SQLException e) { - throw new RuntimeException("Error updating lock in DB: " + e.getMessage(), e); - } - } - - public ResourceLock getByResourceName(String resourceName) { - String sql = "SELECT * FROM RESOURCE_LOCK WHERE resource_name = ?"; - - try (PreparedStatement ps = con.prepareStatement(sql)) { - ps.setString(1, resourceName); - try (ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - ResourceLock rl = new ResourceLock(); - rl.id = rs.getLong("resource_lock_id"); - rl.resourceName = rs.getString("resource_name"); - rl.lockHolder = rs.getString("lock_holder"); - rl.lockCount = rs.getInt("lock_count"); - rl.lockTime = rs.getTimestamp("lock_time"); - rl.expirationTime = rs.getTimestamp("expiration_time"); - return rl; - } - return null; - } - } catch (SQLException e) { - throw new RuntimeException("Error reading lock from DB: " + e.getMessage(), e); - } - } - - public void delete(long id) { - String sql = "DELETE FROM RESOURCE_LOCK WHERE resource_lock_id = ?"; - - try (PreparedStatement ps = con.prepareStatement(sql)) { - ps.setLong(1, id); - ps.execute(); - } catch (SQLException e) { - throw new RuntimeException("Error deleting lock from DB: " + e.getMessage(), e); - } - } - - public void decrementLockCount(long id) { - String sql = "UPDATE RESOURCE_LOCK SET lock_count = lock_count - 1 WHERE resource_lock_id = ?"; - - try (PreparedStatement ps = con.prepareStatement(sql)) { - ps.setLong(1, id); - ps.execute(); - } catch (SQLException e) { - throw new RuntimeException("Error updating lock count in DB: " + e.getMessage(), e); - } - } - - public void commit() { - try { - con.commit(); - } catch (SQLException e) { - throw new RuntimeException("Error committing DB connection: " + e.getMessage(), e); - } - } - - public void rollback() { - try { - con.rollback(); - } catch (SQLException e) { - } - } - - @Override - public void close() { - try { - con.close(); - } catch (SQLException e) { - } - } + private Connection con; + + public ResourceLockDao(DataSource dataSource) { + try { + con = dataSource.getConnection(); + con.setAutoCommit(false); + } catch (SQLException e) { + throw new RuntimeException("Error getting DB connection: " + e.getMessage(), e); + } + } + + public void add(ResourceLock l) { + String sql = "INSERT INTO RESOURCE_LOCK (resource_name, lock_holder, lock_count, lock_time, expiration_time)\n" + + "VALUES (?, ?, ?, ?, ?)"; + + try (PreparedStatement ps = con.prepareStatement(sql)) { + ps.setString(1, l.resourceName); + ps.setString(2, l.lockHolder); + ps.setInt(3, l.lockCount); + ps.setTimestamp(4, new Timestamp(l.lockTime.getTime())); + ps.setTimestamp(5, new Timestamp(l.expirationTime.getTime())); + ps.execute(); + } catch (SQLException e) { + throw new RuntimeException("Error adding lock to DB: " + e.getMessage(), e); + } + } + + public void update(long id, String lockHolder, Date lockTime, Date expirationTime, int lockCount) { + String sql = + "UPDATE RESOURCE_LOCK SET lock_holder = ?, lock_time = ?, expiration_time = ?, lock_count = ?\n" + + "WHERE resource_lock_id = ?"; + + try (PreparedStatement ps = con.prepareStatement(sql)) { + ps.setString(1, lockHolder); + ps.setTimestamp(2, new Timestamp(lockTime.getTime())); + ps.setTimestamp(3, new Timestamp(expirationTime.getTime())); + ps.setInt(4, lockCount); + ps.setLong(5, id); + ps.execute(); + } catch (SQLException e) { + throw new RuntimeException("Error updating lock in DB: " + e.getMessage(), e); + } + } + + public ResourceLock getByResourceName(String resourceName) { + String sql = "SELECT * FROM RESOURCE_LOCK WHERE resource_name = ?"; + + try (PreparedStatement ps = con.prepareStatement(sql)) { + ps.setString(1, resourceName); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + ResourceLock rl = new ResourceLock(); + rl.id = rs.getLong("resource_lock_id"); + rl.resourceName = rs.getString("resource_name"); + rl.lockHolder = rs.getString("lock_holder"); + rl.lockCount = rs.getInt("lock_count"); + rl.lockTime = rs.getTimestamp("lock_time"); + rl.expirationTime = rs.getTimestamp("expiration_time"); + return rl; + } + return null; + } + } catch (SQLException e) { + throw new RuntimeException("Error reading lock from DB: " + e.getMessage(), e); + } + } + + public void delete(long id) { + String sql = "DELETE FROM RESOURCE_LOCK WHERE resource_lock_id = ?"; + + try (PreparedStatement ps = con.prepareStatement(sql)) { + ps.setLong(1, id); + ps.execute(); + } catch (SQLException e) { + throw new RuntimeException("Error deleting lock from DB: " + e.getMessage(), e); + } + } + + public void decrementLockCount(long id) { + String sql = "UPDATE RESOURCE_LOCK SET lock_count = lock_count - 1 WHERE resource_lock_id = ?"; + + try (PreparedStatement ps = con.prepareStatement(sql)) { + ps.setLong(1, id); + ps.execute(); + } catch (SQLException e) { + throw new RuntimeException("Error updating lock count in DB: " + e.getMessage(), e); + } + } + + public void commit() { + try { + con.commit(); + } catch (SQLException e) { + throw new RuntimeException("Error committing DB connection: " + e.getMessage(), e); + } + } + + public void rollback() { + try { + con.rollback(); + } catch (SQLException e) { + } + } + + @Override + public void close() { + try { + con.close(); + } catch (SQLException e) { + } + } } diff --git a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockedException.java b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockedException.java index 7c8cfa122..c79c00f57 100644 --- a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockedException.java +++ b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/ResourceLockedException.java @@ -1,20 +1,33 @@ package org.onap.ccsdk.features.lib.rlock; +/** + * <p> + * This exception is thrown by {@link LockHelper#lock(String, String, int) LockHelper.lock} methods, + * if a requested resource cannot be locked. This might happen, because another threads keeps a + * resource locked for a long time or there is a stale lock that hasn't expired yet. + * </p> + * <p> + * The exception message will contain the locked resource and what lock requester (thread) holds the + * resource locked. + * </p> + * + * @see LockHelperImpl + */ public class ResourceLockedException extends RuntimeException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private String lockName, lockHolder, lockRequester; + private String lockName, lockHolder, lockRequester; - public ResourceLockedException(String lockName, String lockHolder, String lockRequester) { - this.lockName = lockName; - this.lockHolder = lockHolder; - this.lockRequester = lockRequester; - } + public ResourceLockedException(String lockName, String lockHolder, String lockRequester) { + this.lockName = lockName; + this.lockHolder = lockHolder; + this.lockRequester = lockRequester; + } - @Override - public String getMessage() { - return "Failed to lock [" + lockName + "] for [" + lockRequester + "]. Currently locked by [" + lockHolder + - "]."; - } + @Override + public String getMessage() { + return "Failed to lock [" + lockName + "] for [" + lockRequester + "]. Currently locked by [" + lockHolder + + "]."; + } } diff --git a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/SynchronizedFunction.java b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/SynchronizedFunction.java index ff25e16f0..e92700055 100644 --- a/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/SynchronizedFunction.java +++ b/lib/rlock/src/main/java/org/onap/ccsdk/features/lib/rlock/SynchronizedFunction.java @@ -4,32 +4,101 @@ import java.util.Collection; import java.util.HashSet; import java.util.Set; +/** + * <p> + * A simple abstract base class, providing functionality similar to the <tt>synchronized</tt> block + * in Java. Derived class provides the set of resources that need synchronized access and the + * processing method that is executed while the set of resources is locked (override <tt>_exec</tt> + * method). This class uses the {@link LockHelper} service to lock the resources, execute the + * processing method and then unlock the resources. + * </p> + * <p> + * Example: + * </p> + * + * <pre style="color:darkblue;"> + * public class BandwidthCheckFunction extends SynchronizedFunction { + * + * private PortBandwidthDao portBandwidthDao; + * private int neededBandwidth; + * private int bandwidthLimit; + * + * private boolean successful; // Output + * + * public BandwidthCheckFunction(LockHelper lockHelper, PortBandwidthDao portBandwidthDao, String portId, + * int neededBandwidth, int bandwidthLimit) { + * super(lockHelper, Collections.singleton(portId + "-Bandwidth"), 60); // 60 sec lockTimeout + * this.portBandwidthDao = portBandwidthDao; + * this.neededBandwidth = neededBandwidth; + * this.bandwidthLimit = bandwidthLimit; + * } + * + * {@literal @}Override + * protected void _exec() { + * int usedBandwidth = portBandwidthDao.readUsedBandwidth("Port-123"); + * if (usedBandwidth + neededBandwidth <= bandwidthLimit) { + * portBandwidthDao.updateUsedBandwidth("Port-123", usedBandwidth + neededBandwidth); + * successful = true; + * } else { + * successful = false; + * } + * } + * + * public boolean isSuccessful() { + * return successful; + * } + * } + * + * .......... + * + * BandwidthCheckFunction func = new BandwidthCheckFunction(lockHelper, portBandwidthDao, "Port-123", 100, 1000); + * func.exec(); + * boolean success = func.isSuccessful(); + * .......... + * </pre> + * + * @see LockHelper + */ public abstract class SynchronizedFunction { - private Set<String> synchset; - private String lockRequester; - private int lockTimeout; // Seconds - private LockHelper lockHelper; + private Set<String> syncSet; + private String lockRequester; + private int lockTimeout; // Seconds + private LockHelper lockHelper; - protected SynchronizedFunction(LockHelper lockHelper, Collection<String> synchset, int lockTimeout) { - this.lockHelper = lockHelper; - this.synchset = new HashSet<String>(synchset); - this.lockRequester = generateLockRequester(); - this.lockTimeout = lockTimeout; - } + /** + * @param lockHelper {@link LockHelper} service implementation + * @param syncSet the set of resources to be locked during processing + * @param lockTimeout the lock expiration timeout (see {@link LockHelper#lock(String, String, int) + * LockHelper.lock}) + */ + protected SynchronizedFunction(LockHelper lockHelper, Collection<String> syncSet, int lockTimeout) { + this.lockHelper = lockHelper; + this.syncSet = new HashSet<>(syncSet); + lockRequester = generateLockRequester(); + this.lockTimeout = lockTimeout; + } - protected abstract void _exec(); + /** + * Implement this method with the required processing. This method is executed while the resources + * are locked (<tt>syncSet</tt> provided in the constructor). + */ + protected abstract void _exec(); - public void exec() { - lockHelper.lock(synchset, lockRequester, lockTimeout); - try { - _exec(); - } finally { - lockHelper.unlock(synchset, true); - } - } + /** + * Call this method to execute the provided processing in the derived class (the implemented + * <tt>_exec</tt> method). + */ + public void exec() { + lockHelper.lock(syncSet, lockRequester, lockTimeout); + try { + _exec(); + } finally { + lockHelper.unlock(syncSet, true); + } + } - private static String generateLockRequester() { - return "SynchronizedFunction-" + (int) (Math.random() * 1000000); - } + private static String generateLockRequester() { + return "SynchronizedFunction-" + (int) (Math.random() * 1000000); + } } diff --git a/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/TestLockHelper.java b/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/TestLockHelper.java index 9f37894c9..cce377e2c 100644 --- a/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/TestLockHelper.java +++ b/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/TestLockHelper.java @@ -7,10 +7,10 @@ import org.slf4j.LoggerFactory; public class TestLockHelper { - private static final Logger log = LoggerFactory.getLogger(TestLockHelper.class); + private static final Logger log = LoggerFactory.getLogger(TestLockHelper.class); - @Test - public void test1() throws Exception { + @Test + public void test1() throws Exception { LockThread t1 = new LockThread("req1"); LockThread t2 = new LockThread("req2"); LockThread t3 = new LockThread("req3"); @@ -22,30 +22,30 @@ public class TestLockHelper { t1.join(); t2.join(); t3.join(); - } + } - private class LockThread extends Thread { + private class LockThread extends Thread { - private String requester; + private String requester; - public LockThread(String requester) { - this.requester = requester; - } + public LockThread(String requester) { + this.requester = requester; + } - @Override - public void run() { - LockHelperImpl lockHelper = new LockHelperImpl(); - lockHelper.setDataSource(DbUtil.getDataSource()); + @Override + public void run() { + LockHelperImpl lockHelper = new LockHelperImpl(); + lockHelper.setDataSource(DbUtil.getDataSource()); - lockHelper.lock("resource1", requester, 20); + lockHelper.lock("resource1", requester, 20); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - log.warn("Thread interrupted: " + e.getMessage(), e); - } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + log.warn("Thread interrupted: " + e.getMessage(), e); + } - lockHelper.unlock("resource1", false); - } - } + lockHelper.unlock("resource1", false); + } + } } diff --git a/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/DbUtil.java b/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/DbUtil.java index 38d4d62c1..954b532cb 100644 --- a/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/DbUtil.java +++ b/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/DbUtil.java @@ -6,87 +6,83 @@ import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; - import javax.sql.DataSource; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DbUtil { - private static final Logger log = LoggerFactory.getLogger(DbUtil.class); - - private static DataSource dataSource = null; - - public static synchronized DataSource getDataSource() { - if (dataSource == null) { - String url = "jdbc:h2:mem:app;DB_CLOSE_DELAY=-1"; - - dataSource = new DataSource() { - - @Override - public <T> T unwrap(Class<T> arg0) throws SQLException { - return null; - } - - @Override - public boolean isWrapperFor(Class<?> arg0) throws SQLException { - return false; - } - - @Override - public void setLoginTimeout(int arg0) throws SQLException { - } - - @Override - public void setLogWriter(PrintWriter arg0) throws SQLException { - } - - @Override - public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { - return null; - } - - @Override - public int getLoginTimeout() throws SQLException { - return 0; - } - - @Override - public PrintWriter getLogWriter() throws SQLException { - return null; - } - - @Override - public Connection getConnection(String username, String password) throws SQLException { - return null; - } - - @Override - public Connection getConnection() throws SQLException { - return DriverManager.getConnection(url); - } - }; - - try { - String script = FileUtil.read("/schema.sql"); - - String[] sqlList = script.split(";"); - try (Connection con = dataSource.getConnection()) { - for (String sql : sqlList) { - if (!sql.trim().isEmpty()) { - sql = sql.trim(); - try (PreparedStatement ps = con.prepareStatement(sql)) { - log.info("Executing statement:\n" + sql); - ps.execute(); - } - } - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - return dataSource; - } + private static final Logger log = LoggerFactory.getLogger(DbUtil.class); + + private static DataSource dataSource = null; + + public static synchronized DataSource getDataSource() { + if (dataSource == null) { + String url = "jdbc:h2:mem:app;DB_CLOSE_DELAY=-1"; + + dataSource = new DataSource() { + + @Override + public <T> T unwrap(Class<T> arg0) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class<?> arg0) throws SQLException { + return false; + } + + @Override + public void setLoginTimeout(int arg0) throws SQLException {} + + @Override + public void setLogWriter(PrintWriter arg0) throws SQLException {} + + @Override + public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { + return null; + } + + @Override + public int getLoginTimeout() throws SQLException { + return 0; + } + + @Override + public PrintWriter getLogWriter() throws SQLException { + return null; + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + return null; + } + + @Override + public Connection getConnection() throws SQLException { + return DriverManager.getConnection(url); + } + }; + + try { + String script = FileUtil.read("/schema.sql"); + + String[] sqlList = script.split(";"); + try (Connection con = dataSource.getConnection()) { + for (String sql : sqlList) { + if (!sql.trim().isEmpty()) { + sql = sql.trim(); + try (PreparedStatement ps = con.prepareStatement(sql)) { + log.info("Executing statement:\n" + sql); + ps.execute(); + } + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + return dataSource; + } } diff --git a/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/FileUtil.java b/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/FileUtil.java index e51a3b082..5c4ccbf21 100644 --- a/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/FileUtil.java +++ b/lib/rlock/src/test/java/org/onap/ccsdk/features/lib/rlock/testutils/FileUtil.java @@ -6,19 +6,19 @@ import java.io.InputStreamReader; public class FileUtil { - public static String read(String fileName) throws Exception { - String ss = ""; - try (InputStream is = DbUtil.class.getResourceAsStream(fileName)) { - try (InputStreamReader isr = new InputStreamReader(is)) { - try (BufferedReader in = new BufferedReader(isr)) { - String s = in.readLine(); - while (s != null) { - ss += s + '\n'; - s = in.readLine(); - } - } - } - } - return ss; - } + public static String read(String fileName) throws Exception { + String ss = ""; + try (InputStream is = FileUtil.class.getResourceAsStream(fileName)) { + try (InputStreamReader isr = new InputStreamReader(is)) { + try (BufferedReader in = new BufferedReader(isr)) { + String s = in.readLine(); + while (s != null) { + ss += s + '\n'; + s = in.readLine(); + } + } + } + } + return ss; + } } diff --git a/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/OperatorStateBuilder.java b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/OperatorStateBuilder.java new file mode 100644 index 000000000..7e8327a09 --- /dev/null +++ b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/OperatorStateBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.alarms.rev190911; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class OperatorStateBuilder { + private OperatorStateBuilder() { + //Exists only to defeat instantiation. + } + + public static OperatorState getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/ResourceBuilder.java b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/ResourceBuilder.java new file mode 100644 index 000000000..7c4a63d2b --- /dev/null +++ b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/ResourceBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.alarms.rev190911; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class ResourceBuilder { + private ResourceBuilder() { + //Exists only to defeat instantiation. + } + + public static Resource getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/ResourceMatchBuilder.java b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/ResourceMatchBuilder.java new file mode 100644 index 000000000..282a6a26d --- /dev/null +++ b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/ResourceMatchBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.alarms.rev190911; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class ResourceMatchBuilder { + private ResourceMatchBuilder() { + //Exists only to defeat instantiation. + } + + public static ResourceMatch getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/SeverityWithClearBuilder.java b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/SeverityWithClearBuilder.java new file mode 100644 index 000000000..81391922d --- /dev/null +++ b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/SeverityWithClearBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.alarms.rev190911; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class SeverityWithClearBuilder { + private SeverityWithClearBuilder() { + //Exists only to defeat instantiation. + } + + public static SeverityWithClear getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/alarms/ControlMaxAlarmStatusChangesBuilder.java b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/alarms/ControlMaxAlarmStatusChangesBuilder.java new file mode 100644 index 000000000..9f10ae87f --- /dev/null +++ b/sdnr/wt/common-yang/ietf-alarms/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/alarms/rev190911/alarms/ControlMaxAlarmStatusChangesBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.alarms.rev190911.alarms; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class ControlMaxAlarmStatusChangesBuilder { + private ControlMaxAlarmStatusChangesBuilder() { + //Exists only to defeat instantiation. + } + + public static Control.MaxAlarmStatusChanges getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/pom.xml b/sdnr/wt/common-yang/pom.xml index 19a2a0f2e..01bde5e0c 100755 --- a/sdnr/wt/common-yang/pom.xml +++ b/sdnr/wt/common-yang/pom.xml @@ -44,6 +44,7 @@ <module>rfc8341</module> <module>rfc7317-ietf-system</module> <module>ietf-alarms</module> + <module>utils</module> </modules> </project> diff --git a/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/RuleListGroupBuilder.java b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/RuleListGroupBuilder.java new file mode 100644 index 000000000..31142806f --- /dev/null +++ b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/RuleListGroupBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.acm.rev180214.nacm; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class RuleListGroupBuilder { + private RuleListGroupBuilder() { + //Exists only to defeat instantiation. + } + + public static RuleList.Group getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/RuleAccessOperationsBuilder.java b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/RuleAccessOperationsBuilder.java new file mode 100644 index 000000000..91ae639c6 --- /dev/null +++ b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/RuleAccessOperationsBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.acm.rev180214.nacm.rule.list; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class RuleAccessOperationsBuilder { + private RuleAccessOperationsBuilder() { + //Exists only to defeat instantiation. + } + + public static Rule.AccessOperations getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/RuleModuleNameBuilder.java b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/RuleModuleNameBuilder.java new file mode 100644 index 000000000..acf011231 --- /dev/null +++ b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/RuleModuleNameBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.acm.rev180214.nacm.rule.list; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class RuleModuleNameBuilder { + private RuleModuleNameBuilder() { + //Exists only to defeat instantiation. + } + + public static Rule.ModuleName getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/rule/rule/type/NotificationNotificationNameBuilder.java b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/rule/rule/type/NotificationNotificationNameBuilder.java new file mode 100644 index 000000000..7aca26b8c --- /dev/null +++ b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/rule/rule/type/NotificationNotificationNameBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.acm.rev180214.nacm.rule.list.rule.rule.type; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class NotificationNotificationNameBuilder { + private NotificationNotificationNameBuilder() { + //Exists only to defeat instantiation. + } + + public static Notification.NotificationName getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/rule/rule/type/ProtocolOperationRpcNameBuilder.java b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/rule/rule/type/ProtocolOperationRpcNameBuilder.java new file mode 100644 index 000000000..3610df21f --- /dev/null +++ b/sdnr/wt/common-yang/rfc8341/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/acm/rev180214/nacm/rule/list/rule/rule/type/ProtocolOperationRpcNameBuilder.java @@ -0,0 +1,23 @@ +package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.acm.rev180214.nacm.rule.list.rule.rule.type; +import java.lang.String; +import java.lang.UnsupportedOperationException; + +/** + * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation. + * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32). + * + * The reason behind putting it under src/main/java is: + * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent + * loss of user code. + * + */ +public class ProtocolOperationRpcNameBuilder { + private ProtocolOperationRpcNameBuilder() { + //Exists only to defeat instantiation. + } + + public static ProtocolOperation.RpcName getDefaultInstance(String defaultValue) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/sdnr/wt/common-yang/utils/pom.xml b/sdnr/wt/common-yang/utils/pom.xml new file mode 100644 index 000000000..ef3c22b4c --- /dev/null +++ b/sdnr/wt/common-yang/utils/pom.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ============LICENSE_START======================================================= + ~ ONAP : ccsdk features + ~ ================================================================================ + ~ Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. + ~ All rights reserved. + ~ ================================================================================ + ~ Update Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END======================================================= + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.2.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> + <artifactId>sdnr-wt-yang-utils</artifactId> + <version>1.2.0-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-features :: ${project.artifactId}</name> + <licenses> + <license> + <name>Apache License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0</url> + </license> + </licenses> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.code.findbugs</groupId> + <artifactId>annotations</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId> + <artifactId>rfc6991-ietf-yang-types</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> + +</project> diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/YangToolsMapper.java index e7580c69a..f406ea97d 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/YangToolsMapper.java @@ -19,15 +19,16 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.KeyDeserializer; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions.YangToolsBuilderAnnotationIntrospector; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions.YangToolsModule; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsBuilderAnnotationIntrospector; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +41,8 @@ public class YangToolsMapper extends ObjectMapper { @SuppressWarnings("unused") private final Logger LOG = LoggerFactory.getLogger(YangToolsMapper.class); + private final YangToolsBuilderAnnotationIntrospector annotationIntrospector; + private final YangToolsModule module; private static final long serialVersionUID = 1L; public YangToolsMapper() { @@ -49,12 +52,22 @@ public class YangToolsMapper extends ObjectMapper { protected YangToolsMapper(YangToolsBuilderAnnotationIntrospector yangToolsBuilderAnnotationIntrospector) { super(); + this.annotationIntrospector = yangToolsBuilderAnnotationIntrospector; + this.module = new YangToolsModule(); configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); setSerializationInclusion(Include.NON_NULL); enable(MapperFeature.USE_GETTERS_AS_SETTERS); setAnnotationIntrospector(yangToolsBuilderAnnotationIntrospector); - registerModule(new YangToolsModule()); + registerModule(this.module); + + } + public void addDeserializer(Class<?> clsToDeserialize, String builderClassName) { + this.annotationIntrospector.addDeserializer(clsToDeserialize, builderClassName); + } + + public void addKeyDeserializer(Class<?> type, KeyDeserializer deserializer) { + this.module.addKeyDeserializer(type, deserializer); } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper2.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/YangToolsMapper2.java index a19f114e3..5c5aeb6de 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapper2.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/YangToolsMapper2.java @@ -19,12 +19,12 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper; import java.lang.reflect.InvocationTargetException; import javax.annotation.Nullable; import org.eclipse.jdt.annotation.NonNull; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions.YangToolsBuilderAnnotationIntrospector; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsBuilderAnnotationIntrospector; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.slf4j.Logger; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapperHelper.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/YangToolsMapperHelper.java index a2afab0a8..ac6b1b5c5 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/YangToolsMapperHelper.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/YangToolsMapperHelper.java @@ -19,19 +19,26 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper; import com.fasterxml.jackson.databind.DeserializationContext; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.EventInstantAware; +import org.opendaylight.yangtools.yang.binding.Notification; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; @@ -43,6 +50,8 @@ public class YangToolsMapperHelper { private static final Logger LOG = LoggerFactory.getLogger(YangToolsMapperHelper.class); private static final String TYPEOBJECT_INSTANCE_METHOD = "getDefaultInstance"; private static final String BUILDER = "Builder"; + private static final DateTimeFormatter formatterOutput = + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.S'Z'").withZone(ZoneOffset.UTC); private static BundleContext context = getBundleContext(); private static ConcurrentHashMap<String, Class<?>> cache = new ConcurrentHashMap<>(); @@ -201,6 +210,9 @@ public class YangToolsMapperHelper { } public static boolean implementsInterface(Class<?> clz, Class<?> ifToImplement) { + if(clz.equals(ifToImplement)) { + return true; + } Class<?>[] ifs = clz.getInterfaces(); for (Class<?> iff : ifs) { if (iff.equals(ifToImplement)) { @@ -241,4 +253,18 @@ public class YangToolsMapperHelper { Bundle bundle = FrameworkUtil.getBundle(YangToolsMapperHelper.class); return bundle != null ? bundle.getBundleContext() : null; } + public static boolean hasTime(Notification notification) { + return notification instanceof EventInstantAware; + } + public static DateAndTime getTime(Notification notification, Instant defaultValue) { + Instant time; + if (hasTime(notification)) { // If notification class extends/implements the EventInstantAware + time = ((EventInstantAware) notification).eventInstant(); + LOG.debug("Event time {}", time); + } else { + time = defaultValue; + LOG.debug("Defaulting to actual time of processing the notification - {}", time); + } + return DateAndTime.getDefaultInstance(ZonedDateTime.ofInstant(time, ZoneOffset.UTC).format(formatterOutput)); + } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/builder/DateAndTimeBuilder.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/builder/DateAndTimeBuilder.java index 8dbaf4ab9..f6afc578f 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/builder/DateAndTimeBuilder.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/builder/DateAndTimeBuilder.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.builder; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.builder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/mapperextensions/YangToolsBuilderAnnotationIntrospector.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/mapperextensions/YangToolsBuilderAnnotationIntrospector.java index eb611c602..46c966076 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/mapperextensions/YangToolsBuilderAnnotationIntrospector.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/mapperextensions/YangToolsBuilderAnnotationIntrospector.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder.Value; @@ -31,12 +31,10 @@ import java.math.BigInteger; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.builder.DateAndTimeBuilder; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.builder.DateAndTimeBuilder; //import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.builders.rev201110.read.network.element.connection.list.output.DataBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder; import org.opendaylight.yangtools.yang.common.Uint16; import org.opendaylight.yangtools.yang.common.Uint32; import org.opendaylight.yangtools.yang.common.Uint64; @@ -61,7 +59,7 @@ public class YangToolsBuilderAnnotationIntrospector extends JacksonAnnotationInt this.customDeserializer.put(cls, builderClass.getName()); } this.customDeserializer.put(DateAndTime.class, DateAndTimeBuilder.class.getName()); - this.customDeserializer.put(Credentials.class, LoginPasswordBuilder.class.getName()); + //this.customDeserializer.put(Credentials.class, LoginPasswordBuilder.class.getName()); } @Override @@ -115,9 +113,13 @@ public class YangToolsBuilderAnnotationIntrospector extends JacksonAnnotationInt if (res == null) { res = super.resolveSetterConflict(config, setter1, setter2); } - LOG.debug("{} (m1={} <=> m2={} => result:{})", setter1.getName(), p1.getSimpleName(), p2.getSimpleName(), - res.getRawParameterType(0).getSimpleName()); - + if(res ==null) { + LOG.warn("unable to resolve setter conflict for {}", setter1.getName()); + } + else { + LOG.debug("{} (m1={} <=> m2={} => result:{})", setter1.getName(), p1.getSimpleName(), p2.getSimpleName(), + res.getRawParameterType(0)==null?"null":res.getRawParameterType(0).getSimpleName()); + } return res; } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/mapperextensions/YangToolsDeserializerModifier.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/mapperextensions/YangToolsDeserializerModifier.java index 634a3bc5b..c12d17e74 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/mapperextensions/YangToolsDeserializerModifier.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/mapperextensions/YangToolsDeserializerModifier.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.BeanDescription; @@ -33,16 +33,14 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.NoSuchElementException; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.ScalarTypeObject; -//import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.ScalarTypeObject; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.YangHelper2; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.BaseIdentityDeserializer; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.ClassDeserializer; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.IdentifierDeserializer; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.TypeObjectDeserializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.BaseIdentityDeserializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.ClassDeserializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.IdentifierDeserializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.TypeObjectDeserializer; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.ScalarTypeObject; import org.opendaylight.yangtools.yang.binding.TypeObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,8 +85,8 @@ public class YangToolsDeserializerModifier extends BeanDeserializerModifier { if (YangToolsMapperHelper.implementsInterface(rawClass, TypeObject.class)) { deser = new TypeObjectDeserializer<TypeObject>(type, deser); - } else if (YangToolsMapperHelper.implementsInterface(rawClass, YangHelper2.getScalarTypeObjectClass())) { - deser = new TypeObjectDeserializer<ScalarTypeObject>(type, deser); + } else if (YangToolsMapperHelper.implementsInterface(rawClass, ScalarTypeObject.class)) { + deser = new TypeObjectDeserializer<ScalarTypeObject<?>>(type, deser); } else if (YangToolsMapperHelper.implementsInterface(rawClass, BaseIdentity.class)) { deser = new BaseIdentityDeserializer<BaseIdentity>(deser); } else if (rawClass.equals(Class.class)) { @@ -110,8 +108,4 @@ public class YangToolsDeserializerModifier extends BeanDeserializerModifier { LOG.debug("Keydeserialize '{}' with deserializer '{}'", type.getRawClass().getName(), res.getClass().getName()); return res; } - - void test() { - com.fasterxml.jackson.databind.util.ClassUtil xy; - } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/mapperextensions/YangToolsModule.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/mapperextensions/YangToolsModule.java index 46f69d4f9..02628dc16 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/mapperextensions/YangToolsModule.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/mapperextensions/YangToolsModule.java @@ -19,17 +19,16 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions; import com.fasterxml.jackson.databind.module.SimpleModule; import java.util.Map; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.DateAndTimeSerializer; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.EnumSerializer; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.IdentifierDeserializer; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.MapSerializer; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize.TypeObjectSerializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.DateAndTimeSerializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.EnumSerializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.MapSerializer; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.TypeObjectSerializer; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.pmdata.grp.MeasurementKey; +import org.opendaylight.yangtools.yang.binding.ScalarTypeObject; import org.opendaylight.yangtools.yang.binding.TypeObject; public class YangToolsModule extends SimpleModule { @@ -40,11 +39,12 @@ public class YangToolsModule extends SimpleModule { super(); setDeserializerModifier(new YangToolsDeserializerModifier()); - addKeyDeserializer(MeasurementKey.class, new IdentifierDeserializer()); addSerializer(DateAndTime.class, new DateAndTimeSerializer()); addSerializer(TypeObject.class, new TypeObjectSerializer()); + addSerializer(ScalarTypeObject.class, new TypeObjectSerializer()); addSerializer(Enum.class, new EnumSerializer()); addSerializer(Map.class, new MapSerializer()); + } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/BaseIdentityDeserializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/BaseIdentityDeserializer.java index 10f18e796..f85f80e2c 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/BaseIdentityDeserializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/BaseIdentityDeserializer.java @@ -19,14 +19,14 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/ClassDeserializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/ClassDeserializer.java index 2627c2ae0..9d221f504 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/ClassDeserializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/ClassDeserializer.java @@ -19,12 +19,12 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.FromStringDeserializer; import java.io.IOException; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; public class ClassDeserializer extends FromStringDeserializer<Class<?>> { diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/DateAndTimeSerializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/DateAndTimeSerializer.java index a35aad75a..f4fd87580 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/DateAndTimeSerializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/DateAndTimeSerializer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/EnumSerializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/EnumSerializer.java index f8220c2d4..55a20d6c0 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/EnumSerializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/EnumSerializer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/IdentifierDeserializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/IdentifierDeserializer.java index 0837b8a19..6c4c25eb1 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/IdentifierDeserializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/IdentifierDeserializer.java @@ -19,14 +19,14 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.KeyDeserializer; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.List; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; import org.opendaylight.yangtools.yang.common.Uint16; import org.opendaylight.yangtools.yang.common.Uint32; import org.opendaylight.yangtools.yang.common.Uint64; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/MapSerializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/MapSerializer.java index e5c966a74..63689c098 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/MapSerializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/MapSerializer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/TypeObjectDeserializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/TypeObjectDeserializer.java index 5beca0d47..b857a2ffb 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/TypeObjectDeserializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/TypeObjectDeserializer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; @@ -30,7 +30,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.NoSuchElementException; import java.util.Optional; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; import org.opendaylight.yangtools.concepts.Builder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/TypeObjectSerializer.java b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/TypeObjectSerializer.java index 1269d0746..b43e6c100 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/serialize/TypeObjectSerializer.java +++ b/sdnr/wt/common-yang/utils/src/main/java/org/onap/ccsdk/features/sdnr/wt/yang/mapper/serialize/TypeObjectSerializer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.serialize; +package org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; @@ -38,9 +38,10 @@ public class TypeObjectSerializer extends JsonSerializer<TypeObject> { String name; for (Method method : methods) { name = method.getName(); - if (name.equals("stringValue") || name.equals("getValue")) { + if (method.getParameterCount()==0 && (name.equals("stringValue") || name.equals("getValue"))) { try { gen.writeString((String)method.invoke(value)); + break; } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IOException e) { throw new IOException("No String getter method supported TypeObject for "+value.getClass(),e); diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java index f8734d5a6..1f67e5ef8 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/ExtRestClient.java @@ -29,10 +29,8 @@ import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.spec.InvalidKeySpecException; import java.text.ParseException; - import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; - import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; @@ -140,57 +138,6 @@ public class ExtRestClient { } } - // private class SSLCercAuthHttpClientConfigCallback implements HttpClientConfigCallback { - // - // private final String certFilename; - // - // SSLCercAuthHttpClientConfigCallback(String certfile) { - // this.certFilename = certfile; - // } - // - // @Override - // public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { - // if (this.certFilename == null) { - // return httpClientBuilder; - // } - // - // char[] keystorePass = "MY PASSWORD".toCharArray(); - // - // FileInputStream fis = null; - // - // // Loading KEYSTORE in JKS format - // KeyStore keyStorePci = null; - // try { - // keyStorePci = KeyStore.getInstance(KeyStore.getDefaultType()); - // } catch (KeyStoreException e1) { - // LOG.warn("unable to load keystore: {}",e1); - // } - // if (keyStorePci != null) { - // try { - // fis = new FileInputStream(this.certFilename); - // keyStorePci.load(fis, keystorePass); - // } catch (Exception e) { - // LOG.error("Error loading keystore: " + this.certFilename); - // } finally { - // if (fis != null) { - // try { - // fis.close(); - // } catch (IOException e) { - // - // } - // } - // } - // } - // SSLContext sslcontext=null; - // try { - // sslcontext = SSLContexts.custom().loadKeyMaterial(keyStorePci, keystorePass).build(); - // } catch (KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException - // | KeyStoreException e) { - // LOG.warn("unable to load sslcontext: {}",e); - // } - // return httpClientBuilder.setSSLContext(sslcontext); - // } - // } private final RestClient client; private final boolean isES7; @@ -298,7 +245,7 @@ public class ExtRestClient { /** * Search for database entries - * + * * @param request inputRequest * @param ignoreParseException especially for usercreated filters which may cause ES server response exceptions * @return Response with related entries diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/data/DbFilter.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/data/DbFilter.java index 82c036406..70e41c280 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/data/DbFilter.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/data/DbFilter.java @@ -37,9 +37,28 @@ public class DbFilter { return restFilterValue == null ? false : restFilterValue.contains("*") || restFilterValue.contains("?"); } + public static boolean hasSearchParams(List<String> restFilterValues) { + for (String restFilterValue : restFilterValues) { + if (!hasSearchParams(restFilterValue)) { + return false; + } + } + return true; + } + public static boolean isComparisonValid(String restFilterValue) { return restFilterValue == null ? false : restFilterValue.contains(">") || restFilterValue.contains("<"); } + + public static boolean isComparisonValid(List<String> restFilterValues) { + for (String restFilterValue : restFilterValues) { + if (!isComparisonValid(restFilterValue)) { + return false; + } + } + return true; + } + public static boolean isDatetimeKeyValue(String key, String value) { return timestampValueNames.contains(key.toLowerCase()); } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java index 7b22fd5e7..582d749d5 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/database/queries/QueryBuilders.java @@ -21,6 +21,7 @@ */ package org.onap.ccsdk.features.sdnr.wt.common.database.queries; +import java.util.List; import org.json.JSONObject; public class QueryBuilders { @@ -34,6 +35,11 @@ public class QueryBuilders { o.put(key, value); return new QueryBuilder().setQuery("term", o); } + public static QueryBuilder multiTermQuery(String key, List<String> value) { + JSONObject o = new JSONObject(); + o.put(key, value); + return new QueryBuilder().setQuery("terms", o); + } public static QueryBuilder matchQuery(String key, Object value) { JSONObject o = new JSONObject(); @@ -41,6 +47,14 @@ public class QueryBuilders { return new QueryBuilder().setQuery("match", o); } + public static QueryBuilder matchQuery(String key, List<?> values) { + BoolQueryBuilder query = boolQuery(); + for (Object value : values) { + query.should(matchQuery(key, value)); + } + return query; + } + public static BoolQueryBuilder boolQuery() { return new BoolQueryBuilder(); } diff --git a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClient.java b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClient.java index 937e2d898..ffb31c676 100644 --- a/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClient.java +++ b/sdnr/wt/common/src/main/java/org/onap/ccsdk/features/sdnr/wt/common/http/BaseHTTPClient.java @@ -370,6 +370,15 @@ public class BaseHTTPClient { return SSLCERT_PEM; } + public static String decodeBasicAuthHeaderUsername(String authHeader) { + if(authHeader.startsWith("Basic")) { + authHeader = authHeader.substring(6); + } + final String decoded = new String(Base64.getDecoder().decode(authHeader)); + String[] tmp = decoded.split(":"); + return tmp.length > 0 ? tmp[0] : null; + } + } diff --git a/sdnr/wt/common/src/test/resources/testpom.xml b/sdnr/wt/common/src/test/resources/testpom.xml index e57fed436..6fba87af9 100644 --- a/sdnr/wt/common/src/test/resources/testpom.xml +++ b/sdnr/wt/common/src/test/resources/testpom.xml @@ -29,13 +29,13 @@ <parent> <groupId>org.onap.ccsdk.parent</groupId> <artifactId>binding-parent</artifactId> - <version>2.1.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <relativePath/> </parent> <groupId>org.onap.ccsdk.features.sdnr.wt</groupId> <artifactId>sdnr-wt-common</artifactId> - <version>1.1.1-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>ccsdk-features :: ${project.artifactId}</name> @@ -63,7 +63,7 @@ </dependency> <dependency> <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> + <artifactId>servlet-api</artifactId> </dependency> <dependency> <groupId>org.osgi</groupId> diff --git a/sdnr/wt/data-provider/installer/pom.xml b/sdnr/wt/data-provider/installer/pom.xml index cdd1724d2..ee6b2f370 100755 --- a/sdnr/wt/data-provider/installer/pom.xml +++ b/sdnr/wt/data-provider/installer/pom.xml @@ -118,27 +118,8 @@ </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> - <version>2.6</version> <executions> <execution> - <id>copy-sdnr-data-migration-tool</id> - <goals> - <goal>copy-resources</goal> - </goals> - <phase>validate</phase> - <configuration> - <outputDirectory>${project.build.directory}/assembly/system/org/onap/ccsdk/features/sdnr/wt/sdnr-wt-data-provider-setup/${project.version}</outputDirectory> - <resources> - <resource> - <directory>${basedir}/../setup/target</directory> - <includes> - <include>sdnr-dmt.jar</include> - </includes> - </resource> - </resources> - </configuration> - </execution> - <execution> <id>copy-schemas</id> <goals> <goal>copy-resources</goal> diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESEvent.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataInconsistencyException.java index 1117565e6..e734a47a3 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESEvent.java +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataInconsistencyException.java @@ -19,26 +19,22 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.dataprovider.model; -import java.util.HashMap; -import java.util.Map; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; -public class VESEvent { +public class DataInconsistencyException extends Exception { - public Map<String, Object> event = new HashMap<String, Object>(); - - public void addEventObjects(Object eventObject) { - if (eventObject instanceof VESCommonEventHeaderPOJO) - event.put("commonEventHeader", eventObject); - else if (eventObject instanceof VESNotificationFieldsPOJO) - event.put("notificationFields", eventObject); + private static final long serialVersionUID = 1L; + private final List<Inventory> repaired; + public DataInconsistencyException(List<Inventory> repaired, String message) { + super(message); + this.repaired = repaired; } - public Map<String, Object> getEvent() { - return event; + public List<Inventory> getRepairedList() { + return this.repaired; } } - - diff --git a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java index d277b763e..e6eb7a4e8 100644 --- a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/DataProvider.java @@ -67,17 +67,22 @@ public interface DataProvider extends ArchiveCleanProvider { /** * write internal equipment to database - * * @param internalEquipment with mandatory fields. */ void writeInventory(Inventory internalEquipment); + /** + * write internal equipment to database + * @param nodeId + * @param list with mandatory fields. + */ + void writeInventory(String nodeId, List<Inventory> list); /** * write GUI Cut through data to database * * @param gcData */ - void writeGuiCutThroughData(Guicutthrough gcData); + void writeGuiCutThroughData(Guicutthrough gcData, String nodeId); /** * diff --git a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/HtUserdataManager.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/HtUserdataManager.java new file mode 100644 index 000000000..2f580c98b --- /dev/null +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/HtUserdataManager.java @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================================== + * ONAP : ccsdk feature sdnr wt + * ================================================================================================= + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved. + * ================================================================================================= + * 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. + * ============LICENSE_END========================================================================== + */ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.model; + +/** + * @author Jack + * + */ +public interface HtUserdataManager { + + String getUserdata(String username); + + String getUserdata(String username, String key); + + boolean setUserdata(String username, String data); + + boolean setUserdata(String username, String key, String data); + + boolean removeUserdata(String username); + + boolean removeUserdata(String username, String key); + +} diff --git a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java index 9ba10cd0b..2a91d7816 100644 --- a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/IEntityDataProvider.java @@ -27,6 +27,8 @@ public interface IEntityDataProvider { /** Get provider to access read/write operations for maintenance **/ public HtDatabaseMaintenance getHtDatabaseMaintenance(); + public HtUserdataManager getHtDatabaseUserManager(); + /** Set overall ready status from outside of this data-provider **/ public void setReadyStatus(boolean status); diff --git a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/types/NetconfTimeStampImpl.java b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/types/NetconfTimeStampImpl.java index bd71d5ba1..2ccebca99 100644 --- a/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/types/NetconfTimeStampImpl.java +++ b/sdnr/wt/data-provider/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/model/types/NetconfTimeStampImpl.java @@ -75,14 +75,14 @@ public class NetconfTimeStampImpl implements NetconfTimeStamp { /** * Specify the input format expected from netconf, and from specific devices. */ - private static DateTimeFormatter formatterInput = + private static final DateTimeFormatter formatterInput = DateTimeFormatter.ofPattern("" + "[yyyy-MM-dd'T'HH:mm[:ss][.SSS][.SS][.S][xxx][xx][X][Z]]" + "[yyyyMMddHHmmss[.SSS][.SS][.S][xxx][xx][X][Z]]").withZone(ZoneOffset.UTC); /** * Specify output format that is used internally */ - private static DateTimeFormatter formatterOutput = + private static final DateTimeFormatter formatterOutput = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.S'Z'").withZone(ZoneOffset.UTC); /** diff --git a/sdnr/wt/data-provider/model/src/main/yang/data-provider@2020-11-10.yang b/sdnr/wt/data-provider/model/src/main/yang/data-provider@2020-11-10.yang index 8509007e1..84c43d52b 100644 --- a/sdnr/wt/data-provider/model/src/main/yang/data-provider@2020-11-10.yang +++ b/sdnr/wt/data-provider/model/src/main/yang/data-provider@2020-11-10.yang @@ -104,6 +104,10 @@ module data-provider { description "list of GUI Cut through entries"; } + enum userdata { + description + "user specific data. id=username"; + } } description "Data type and alias for elasticsearch or table name for SQL database."; @@ -556,7 +560,11 @@ module data-provider { description "An object class describing a mediator server entity."; } - + container mediator-server { + description + "builder"; + uses mediator-server-entity; + } grouping pmdata-base { description "Performance data base information"; @@ -1260,6 +1268,11 @@ module data-provider { description "current connection status. default Disconnected"; } + leaf tls-key { + type string; + description + "TLS key-id in MD-SAL"; + } description "An object class defining the NetConf connection towards a NetConf server. "; @@ -1324,6 +1337,11 @@ module data-provider { description "The filter information for the corresponding property."; } + leaf-list filtervalues { + type string; + description + "The filter information for the corresponding property."; + } description "List with filter criteria. Not listed means all."; } @@ -1406,12 +1424,12 @@ module data-provider { type string; mandatory true; description - "Unique database id, node-id/uuid"; + "Unique database id, node-id"; } leaf name { type string; description - "Mountpoint Name"; + "Name of the system to which a GUI Cutthrough session will be established"; } leaf weburi { type string; diff --git a/sdnr/wt/data-provider/provider/pom.xml b/sdnr/wt/data-provider/provider/pom.xml index 9045dfa12..3507d4108 100644 --- a/sdnr/wt/data-provider/provider/pom.xml +++ b/sdnr/wt/data-provider/provider/pom.xml @@ -48,7 +48,8 @@ <properties> <maven.javadoc.skip>true</maven.javadoc.skip> - <databaseport>49402</databaseport> + <databaseport>49402</databaseport> + <initdb>${basedir}/../setup/target/sdnr-dmt.jar</initdb> </properties> <dependencies> @@ -74,6 +75,11 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>sdnr-wt-yang-utils</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>sdnr-wt-data-provider-model</artifactId> <version>${project.version}</version> </dependency> @@ -159,7 +165,7 @@ <executable>${basedir}/java.sh</executable> <arguments> <argument>-jar</argument> - <argument>${basedir}/../../data-provider/setup/target/sdnr-dmt.jar</argument> + <argument>${initdb}</argument> <argument>-c</argument> <argument>pluginfile</argument> <argument>-of</argument> diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtUserdataManagerImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtUserdataManagerImpl.java new file mode 100644 index 000000000..73cc1a212 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/HtUserdataManagerImpl.java @@ -0,0 +1,150 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.data; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchHit; +import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; +import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HtUserdataManagerImpl implements HtUserdataManager { + + private static final Logger LOG = LoggerFactory.getLogger(HtUserdataManagerImpl.class); + + private static final String USERDATA_DEFAULTS_FILENAME = "etc/userdata-defaults.json"; + private static final JSONObject USERDATA_DEFAULTS_CONTENT = loadDefaults(); + + private static JSONObject loadDefaults() { + File f = new File(USERDATA_DEFAULTS_FILENAME); + String content; + JSONObject o = null; + if (f.exists()) { + try { + content = Files.readString(f.toPath()); + o = new JSONObject(content); + } catch (IOException e) { + LOG.warn("problem loading defaults: ", e); + } catch (JSONException e) { + LOG.warn("problem parsing defaults: ", e); + } + } + return o; + } + + + private final HtDatabaseClient dbClient; + + public HtUserdataManagerImpl(HtDatabaseClient rawClient) { + this.dbClient = rawClient; + } + + @Override + public String getUserdata(String username) { + SearchResult<SearchHit> result = this.dbClient.doReadByQueryJsonData(Entity.Userdata.getName(), + QueryBuilders.matchQuery("_id", username)); + String json = result.getHits().size() > 0 ? result.getHits().get(0).getSourceAsString() : "{}"; + if (USERDATA_DEFAULTS_CONTENT != null) { + JSONObject merge = mergeData(new JSONObject(json), USERDATA_DEFAULTS_CONTENT); + json = merge.toString(); + } + return json; + } + + @Override + public String getUserdata(String username, String key) { + JSONObject o = new JSONObject(this.getUserdata(username)); + return o.has(key) ? o.get(key).toString() : "{}"; + } + + @Override + public boolean setUserdata(String username, String data) { + JSONObject o = new JSONObject(this.getUserdata(username)); + JSONObject merge = mergeData(o, new JSONObject(data)); + return this.dbClient.doWriteRaw(Entity.Userdata.getName(), username, merge.toString()) != null; + } + + @Override + public boolean setUserdata(String username, String key, String data) { + JSONObject o = new JSONObject(this.getUserdata(username)); + o = mergeData(o, key, new JSONObject(data)); + return this.dbClient.doWriteRaw(Entity.Userdata.getName(), username, o.toString()) != null; + } + + @Override + public boolean removeUserdata(String username) { + return this.dbClient.doRemove(Entity.Userdata.getName(), username); + } + + @Override + public boolean removeUserdata(String username, String key) { + JSONObject o = new JSONObject(this.getUserdata(username)); + if (o.has(key)) { + o.remove(key); + return this.setUserdata(username, o.toString()); + } + return true; + } + + private static JSONObject mergeData(JSONObject o, String key, JSONObject subObject) { + if (!o.has(key)) { + o.put(key, subObject); + } else { + JSONObject tmp = new JSONObject(); + tmp.put(key, subObject); + o = mergeData(tmp, o); + } + return o; + } + + private static JSONObject mergeData(JSONObject source, JSONObject target) throws JSONException { + String[] keys = JSONObject.getNames(source); + if (keys == null) { + return target; + } + for (String key : keys) { + Object value = source.get(key); + if (!target.has(key)) { + // new value for "key": + target.put(key, value); + } else { + // existing value for "key" - recursively deep merge: + if (value instanceof JSONObject) { + JSONObject valueJson = (JSONObject) value; + mergeData(valueJson, target.getJSONObject(key)); + } else { + target.put(key, value); + } + } + } + return target; + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/entity/HtDatabaseEventsService.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/entity/HtDatabaseEventsService.java index 0f2f7d250..f680edddf 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/entity/HtDatabaseEventsService.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/entity/HtDatabaseEventsService.java @@ -24,7 +24,10 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.data.entity; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import javax.annotation.Nonnull; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -36,6 +39,7 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.queries.RangeQueryBuilder import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.ElasticSearchDataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.EsDataObjectReaderWriter2; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.ArchiveCleanProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataInconsistencyException; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.NetconfTimeStampImpl; @@ -62,6 +66,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.PmdataEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.PmdataEntityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.UpdateNetworkElementConnectionInputBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -120,8 +125,8 @@ public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvid NetworkElementConnectionEntity.class, NetworkElementConnectionBuilder.class, true) .setEsIdAttributeName("_id"); - guiCutThroughDB = new EsDataObjectReaderWriter2<>(client, Entity.Guicutthrough, - GuicutthroughEntity.class, GuicutthroughBuilder.class); + guiCutThroughDB = new EsDataObjectReaderWriter2<>(client, Entity.Guicutthrough, GuicutthroughEntity.class, + GuicutthroughBuilder.class); pmData15mDB = new EsDataObjectReaderWriter2<>(client, Entity.Historicalperformance15min, PmdataEntity.class, PmdataEntityBuilder.class); @@ -259,22 +264,109 @@ public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvid * * @param internalEquipment with mandatory fields. */ + @Override public void writeInventory(Inventory internalEquipment) { - if (assertIfClientNullForNodeName(internalEquipment.getNodeId())) { - return; - } if (internalEquipment.getManufacturerIdentifier() == null) { internalEquipment = new InventoryBuilder(internalEquipment).setManufacturerIdentifier("").build(); } if (internalEquipment.getDate() == null) { internalEquipment = new InventoryBuilder(internalEquipment).setDate("").build(); } - eventRWEquipment.write(internalEquipment, internalEquipment.getNodeId() + "/" + internalEquipment.getUuid()); } + /** + * write internal equipment to database + * + * @param nodeId + * @param list + */ + @Override + public void writeInventory(String nodeId, List<Inventory> list) { + + try { + checkConsistency(nodeId, list); + } catch (DataInconsistencyException e) { + LOG.warn("inventory list for node {} is not consistent", nodeId, e); + list = e.getRepairedList(); + } + + for (Inventory internalEquipment : list) { + this.writeInventory(internalEquipment); + } + } + + private static void checkConsistency(String nodeId, List<Inventory> list) throws DataInconsistencyException { + final String UNBOUND_INVENTORY_UUID = "unbound"; + List<String> failures = new ArrayList<>(); + long treeLevel; + int failCounter = 0; + Map<String, Inventory> repairList = new HashMap<>(); + InventoryBuilder repairedItem; + InventoryBuilder unboundItem = new InventoryBuilder().setNodeId(nodeId).setUuid(UNBOUND_INVENTORY_UUID) + .setTreeLevel(Uint32.valueOf(0));; + for (Inventory item : list) { + repairedItem = new InventoryBuilder(item); + //check missing tree-level + if (!nodeId.equals(item.getNodeId())) { + failures.add(String.format("missing node-id for equipment(uuid=%s)", item.getUuid())); + repairedItem.setNodeId(nodeId); + failCounter++; + } + if (item.getTreeLevel() == null) { + failures.add(String.format("missing tree-level for equipment(uuid=%s)", item.getUuid())); + repairedItem.setTreeLevel(Uint32.valueOf(1)); + failCounter++; + + } else { + treeLevel = item.getTreeLevel().longValue(); + if (treeLevel > 0) { + //check non root elem and missing parent + if (item.getParentUuid() == null) { + failures.add(String.format("Non root level element (uuid=%s) has to have a parent element", + item.getUuid())); + failCounter++; + repairedItem.setParentUuid(UNBOUND_INVENTORY_UUID); + repairList.put(unboundItem.getUuid(), unboundItem.build()); + } + //check that parent exists in list and is tree-level -1 + else { + Optional<Inventory> parent = + list.stream().filter(e -> item.getParentUuid().equals(e.getUuid())).findFirst(); + if (parent.isEmpty()) { + failures.add(String.format("no parent found for uuid=%s with parent-uuid=%s", + item.getUuid(), item.getParentUuid())); + repairedItem.setParentUuid(UNBOUND_INVENTORY_UUID); + failCounter++; + } + } + } + //check for duplicated uui + Optional<Inventory> duplicate = list + .stream().filter(e -> !item.equals(e) && item.getUuid() != null + && item.getUuid().equals(e.getUuid()) && repairList.containsKey(e.getUuid())) + .findFirst(); + if (duplicate.isPresent()) { + failures.add(String.format("found duplicate uuid=%s", item.getUuid())); + failCounter++; + continue; + + } + if (failCounter > 0) { + repairList.put(repairedItem.getUuid(), repairedItem.build()); + } else { + repairList.put(item.getUuid(), item); + } + } + } + + if (failures.size() > 0) { + throw new DataInconsistencyException(new ArrayList<>(repairList.values()), + "inventory list is not consistent;\n" + String.join("\n", failures)); + } + } // -- Networkelement @@ -530,8 +622,8 @@ public class HtDatabaseEventsService implements ArchiveCleanProvider, DataProvid } @Override - public void writeGuiCutThroughData(Guicutthrough gcData) { - guiCutThroughDB.write(gcData, null); + public void writeGuiCutThroughData(Guicutthrough gcData, String nodeId) { + guiCutThroughDB.write(gcData, nodeId); } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/rpctypehelper/QueryByFilter.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/rpctypehelper/QueryByFilter.java index 09e48197a..627d125ae 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/rpctypehelper/QueryByFilter.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/data/rpctypehelper/QueryByFilter.java @@ -33,7 +33,6 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.data.DbFilter; import org.onap.ccsdk.features.sdnr.wt.common.database.queries.BoolQueryBuilder; import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; -import org.onap.ccsdk.features.sdnr.wt.common.database.queries.RangeQueryBuilder; import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.acessor.DataObjectAcessorPm; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; @@ -76,11 +75,13 @@ public class QueryByFilter { @Nullable Pagination pagination = input.getPagination(); if (pagination != null) { - @Nullable Uint64 pageOrNull = YangHelper2.getUint64(pagination.getPage()); + @Nullable + Uint64 pageOrNull = YangHelper2.getUint64(pagination.getPage()); if (pageOrNull != null) { page = pageOrNull.longValue(); } - @Nullable Uint32 pageSizeOrNull = YangHelper2.getUint32(pagination.getSize()); + @Nullable + Uint32 pageSizeOrNull = YangHelper2.getUint32(pagination.getSize()); if (pageSizeOrNull != null) { pageSize = pageSizeOrNull.longValue(); } @@ -239,7 +240,7 @@ public class QueryByFilter { if (dt == null) { return null; } - // property.substring(0,idx)+REPLACE.substring(idx+1); + // property.substring(0,idx)+REPLACE.substring(idx+1); Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); c.setTime(dt); int tmpvalue; @@ -348,70 +349,54 @@ public class QueryByFilter { } + private static List<String> collectValues(Filter filter) { + List<String> values = new ArrayList<String>(); + if (filter.getFiltervalue() != null) { + values.add(filter.getFiltervalue()); + } + if (filter.getFiltervalues() != null) { + values.addAll(filter.getFiltervalues()); + } + return values; + } + private static QueryBuilder fromFilter(@Nullable List<Filter> filters, String prefix) { if (filters == null || filters.size() == 0) { return QueryBuilders.matchAllQuery(); } else if (filters.size() == 1) { - QueryBuilder query; - String p = filters.get(0).getProperty(); - String v = filters.get(0).getFiltervalue(); - if ("id".equals(p)) { - p = "_id"; - } else { - // v=v.toLowerCase(); + String property = filters.get(0).getProperty(); + List<String> values = collectValues(filters.get(0)); + if ("id".equals(property)) { + property = "_id"; } - if (DbFilter.hasSearchParams(v)) { - if (p != null && timestampValueNames.contains(p.toLowerCase())) { - query = fromTimestampSearchFilter(p, v); - if (query != null) { - return query; - } + if (values.size() == 1) { + return getSinglePropertyQuery(property, values.get(0), prefix); + } else { + BoolQueryBuilder bquery = new BoolQueryBuilder(); + for (String v : values) { + bquery.should(getSinglePropertyQuery(property, v, prefix)); } - return QueryBuilders.regex(p, DbFilter.createDatabaseRegex(v)); + return bquery; - - } else if (DbFilter.isComparisonValid(v)) { - RangeQueryBuilder q = DbFilter.getRangeQuery(handlePrefix(prefix, p), v); - if (q != null) { - return q; - } else { - return QueryBuilders.matchQuery(handlePrefix(prefix, p), v); - } - } else { - return QueryBuilders.matchQuery(handlePrefix(prefix, p), v); } } else { BoolQueryBuilder query = new BoolQueryBuilder(); - QueryBuilder tmpQuery; for (Filter fi : filters) { String p = fi.getProperty(); - String v = fi.getFiltervalue(); + List<String> values = collectValues(fi); if ("id".equals(p)) { p = "_id"; - } else { - // v=v.toLowerCase(); } - if (DbFilter.hasSearchParams(v)) { - if (p != null && timestampValueNames.contains(p.toLowerCase())) { - tmpQuery = fromTimestampSearchFilter(p, v); - if (tmpQuery != null) { - query.must(tmpQuery); - } else { - query.must(QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v))); - } - } else { - query.must(QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v))); - } - } else if (DbFilter.isComparisonValid(v)) { - RangeQueryBuilder q = DbFilter.getRangeQuery(handlePrefix(prefix, p), v); - if (q != null) { - query.must(q); - } else { - query.must(QueryBuilders.matchQuery(handlePrefix(prefix, p), v)); - } + if (values.size() == 1) { + query.must(getSinglePropertyQuery(p, values.get(0), prefix)); } else { - query.must(QueryBuilders.matchQuery(handlePrefix(prefix, p), v)); + BoolQueryBuilder tmpQuery = QueryBuilders.boolQuery(); + for (String v : values) { + tmpQuery.should(getSinglePropertyQuery(p, v, prefix)); + } + query.must(tmpQuery); + tmpQuery = QueryBuilders.boolQuery(); } } LOG.trace("Query result. {}", query.toJSON()); @@ -419,6 +404,28 @@ public class QueryByFilter { } } + private static QueryBuilder getSinglePropertyQuery(String p, String v, String prefix) { + QueryBuilder query = null; + if (DbFilter.hasSearchParams(v)) { + if (p != null && timestampValueNames.contains(p.toLowerCase())) { + query = fromTimestampSearchFilter(p, v); + if (query == null) { + query = QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v)); + } + } else { + query = QueryBuilders.regex(handlePrefix(prefix, p), DbFilter.createDatabaseRegex(v)); + } + } else if (DbFilter.isComparisonValid(v)) { + query = DbFilter.getRangeQuery(handlePrefix(prefix, p), v); + if (query == null) { + query = QueryBuilders.matchQuery(handlePrefix(prefix, p), v); + } + } else { + query = QueryBuilders.matchQuery(handlePrefix(prefix, p), v); + } + return query; + } + private static String handlePrefix(String prefix, String p) { return (prefix != null ? prefix : "") + p; } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java index 603c25bae..153022b4c 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/database/EsDataObjectReaderWriter2.java @@ -32,8 +32,8 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.DatabaseClient; import org.onap.ccsdk.features.sdnr.wt.common.database.SearchHit; import org.onap.ccsdk.features.sdnr.wt.common.database.SearchResult; import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilder; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper2; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapper2; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeChildObject.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeChildObject.java index e34988b4b..91d469700 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeChildObject.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeChildObject.java @@ -26,14 +26,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; - import org.json.JSONObject; public class DataTreeChildObject { private final String label; - private final String ownSeverity; - private final String childrenSeveritySummary; +// private final String ownSeverity; +// private final String childrenSeveritySummary; private final boolean isMatch; private final Map<String, DataTreeChildObject> children; private final Map<String, Object> properties; @@ -47,8 +46,8 @@ public class DataTreeChildObject { this.label = label; this.isMatch = isMatch; this.children = children; - this.ownSeverity = ownSeverity; - this.childrenSeveritySummary = childrenSeveritySummary; +// this.ownSeverity = ownSeverity; +// this.childrenSeveritySummary = childrenSeveritySummary; this.properties = new HashMap<>(); } @@ -104,6 +103,7 @@ public class DataTreeChildObject { itemValue = this.getProperty(childKey, null); if (itemValue != null && itemValue.equals(itemValueToMatch)) { this.children.put(id, data); + return true; } } return false; @@ -189,4 +189,8 @@ public class DataTreeChildObject { this.children.remove(key); } } + + public boolean hasChildren() { + return this.children!=null && !this.children.isEmpty(); + } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java index bb4023abc..115ff4f40 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeHttpServlet.java @@ -48,14 +48,6 @@ import org.slf4j.LoggerFactory; */ public class DataTreeHttpServlet extends HttpServlet { - public enum FilterMode { - Strict, //show only filtered items and their parents - Lazy //show root items (and all their children) which have matches inside - } - - /** - * - */ private static final long serialVersionUID = 1L; private final DataTreeProviderImpl dataTreeProvider; private static final Logger LOG = LoggerFactory.getLogger(DataTreeHttpServlet.class); @@ -116,7 +108,7 @@ public class DataTreeHttpServlet extends HttpServlet { LOG.info("GET request for {} to e={} with tree={}", uri, e.entity, e.tree); switch (e.entity) { case Inventoryequipment: - DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, null, FilterMode.Lazy); + DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, null); this.doJsonResponse(resp, o); break; default: @@ -132,17 +124,12 @@ public class DataTreeHttpServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { final String uri = req.getRequestURI(); String filter = null; - FilterMode mode = FilterMode.Lazy; try { final String body = readPayload(req); JSONObject data = new JSONObject(body); if (data.has("query")) { filter = data.getString("query"); } - if (data.has("mode")) { - mode = data.getString("mode").equals("lazy") ? FilterMode.Lazy : FilterMode.Strict; - } - } catch (Exception e) { LOG.warn("problem reading payload: {}", e); @@ -152,7 +139,7 @@ public class DataTreeHttpServlet extends HttpServlet { if (e != null) { switch (e.entity) { case Inventoryequipment: - DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, filter, mode); + DataTreeObject o = this.dataTreeProvider.readInventoryTree(e.tree, filter); this.doJsonResponse(resp, o); break; default: @@ -208,6 +195,15 @@ public class DataTreeHttpServlet extends HttpServlet { return "EntityWithTree [entity=" + entity + ", tree=" + tree + "]"; } + /** + * + * @param e database enttity to access + * @param tree tree description + * e.g. nodeA => tree entry for node-id=nodeA + * nodeA/key0 => tree entry for node-id=nodeA and uuid=key0 and tree-level=0 + * nodeA/key0/key1 => tree entry for node-id=nodeA and uuid=key1 and tree-level=1 + * + */ public EntityWithTree(Entity e, String tree) { this.entity = e; if (tree != null) { diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeObject.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeObject.java index d6c8bd7bb..f12ff3deb 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeObject.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/DataTreeObject.java @@ -21,8 +21,9 @@ */ package org.onap.ccsdk.features.sdnr.wt.dataprovider.http; +import java.util.ArrayList; import java.util.HashMap; - +import java.util.List; import org.json.JSONObject; public class DataTreeObject extends HashMap<String, DataTreeChildObject> { @@ -95,8 +96,15 @@ public class DataTreeObject extends HashMap<String, DataTreeChildObject> { * */ public void removeUnmatchedPaths() { - for (DataTreeChildObject entry : this.values()) { - entry.removeUnmatchedPaths(); + List<String> toRemove = new ArrayList<>(); + for (Entry<String,DataTreeChildObject> entry : this.entrySet()) { + entry.getValue().removeUnmatchedPaths(); + if(!entry.getValue().isMatch() && !entry.getValue().hasChildren()) { + toRemove.add(entry.getKey()); + } + } + for(String toRemoveKey:toRemove) { + this.remove(toRemoveKey); } } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/UserdataHttpServlet.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/UserdataHttpServlet.java new file mode 100644 index 000000000..09a81c381 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/http/UserdataHttpServlet.java @@ -0,0 +1,175 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.http; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.json.JSONObject; +import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UserdataHttpServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(UserdataHttpServlet.class); + private static final String REGEX = "^\\/userdata[\\/]?([a-zA-Z0-9]+)?$"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final String JWT_PAYLOAD_USERNAME_PROPERTYKEY = "sub"; + private HtUserdataManager dbUserManager; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + final String uri = req.getRequestURI(); + final Matcher matcher = PATTERN.matcher(uri); + if (matcher.find()) { + LOG.info("GET found match"); + this.handleGetRequest(req, resp, matcher.groupCount() > 0 ? matcher.group(1) : null); + } else { + LOG.info("no valid request"); + super.doGet(req, resp); + } + } + + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + final String uri = req.getRequestURI(); + final Matcher matcher = PATTERN.matcher(uri); + if (matcher.find()) { + LOG.info("PUT found match"); + final String payload = getPayload(req); + this.handlePutRequest(req, resp, payload, matcher.groupCount() > 0 ? matcher.group(1) : null); + } else { + LOG.info("no valid request"); + super.doPut(req, resp); + } + } + + private String getPayload(HttpServletRequest req) throws IOException { + return DataTreeHttpServlet.readPayload(req); + } + + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + final String uri = req.getRequestURI(); + final Matcher matcher = PATTERN.matcher(uri); + if (matcher.find()) { + LOG.info("DELETE found match"); + this.handleDeleteRequest(req, resp, matcher.groupCount() > 0 ? matcher.group(1) : null); + } else { + LOG.info("no valid request"); + super.doPut(req, resp); + } + } + + private void handleGetRequest(HttpServletRequest req, HttpServletResponse resp, String key) { + final String username = this.getUsername(req); + if(username==null) { + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + sendJsonResponse(resp, + key == null ? this.dbUserManager.getUserdata(username) : this.dbUserManager.getUserdata(username, key)); + } + + + private void handlePutRequest(HttpServletRequest req, HttpServletResponse resp, String data, String key) { + final String username = this.getUsername(req); + if(username==null) { + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + boolean success = key == null ? this.dbUserManager.setUserdata(username, data) + : this.dbUserManager.setUserdata(username, key, data); + resp.setStatus(success ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + private void handleDeleteRequest(HttpServletRequest req, HttpServletResponse resp, String key) { + final String username = this.getUsername(req); + if(username==null) { + resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + boolean success = key == null ? this.dbUserManager.removeUserdata(username) + : this.dbUserManager.removeUserdata(username, key); + resp.setStatus(success ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + private String getUsername(HttpServletRequest req) { + final String authHeader = req.getHeader("Authorization"); + if(authHeader==null) { + return null; + } + String username = null; + if(authHeader.startsWith("Basic")) { + username = BaseHTTPClient.decodeBasicAuthHeaderUsername(authHeader); + } + else if(authHeader.startsWith("Bearer")) { + username = decodeJWTPayloadUsername(authHeader, JWT_PAYLOAD_USERNAME_PROPERTYKEY); + } + return username; + } + + public static String decodeJWTPayloadUsername(String authHeader, String key) { + String username = null; + if(authHeader.startsWith("Bearer")) { + authHeader = authHeader.substring(7); + } + String[] tmp = authHeader.split("\\."); + if(tmp.length==3) { + final String decoded = new String(Base64.getDecoder().decode(tmp[1])); + JSONObject o = new JSONObject(decoded); + if(o.has(key)) { + username = o.getString(key); + if(username!=null && username.contains("@")) { + username = username.split("@")[0]; + } + } + } + return username; + } + + private static void sendJsonResponse(HttpServletResponse resp, String userdata) { + resp.setContentType("application/json"); + resp.setStatus(HttpServletResponse.SC_OK); + try { + + resp.getOutputStream().write(userdata.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + LOG.warn("problem sending response: ", e); + } + + } + + public void setDatabaseClient(HtUserdataManager dbUserManager) { + this.dbUserManager = dbUserManager; + } + +} diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java index 5c1ea98b2..190c78904 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderImpl.java @@ -26,9 +26,11 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClientException import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.MsServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.ReadyHttpServlet; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.UserdataHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.about.AboutHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEsConfig; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.NetconfTimeStamp; @@ -48,6 +50,7 @@ public class DataProviderImpl implements IEntityDataProvider, AutoCloseable { private DataProviderServiceImpl rpcApiService; private AboutHttpServlet aboutServlet; private DataTreeHttpServlet treeServlet; + private UserdataHttpServlet userdataServlet; private HtDatabaseClient dbClient; // Blueprint 1 @@ -71,7 +74,9 @@ public class DataProviderImpl implements IEntityDataProvider, AutoCloseable { public void setTreeServlet(DataTreeHttpServlet treeServlet) { this.treeServlet = treeServlet; } - + public void setUserdataServlet(UserdataHttpServlet userdataServlet) { + this.userdataServlet = userdataServlet; + } public void init() throws Exception { LOG.info("Session Initiated start {}", APPLICATION_NAME); @@ -79,6 +84,7 @@ public class DataProviderImpl implements IEntityDataProvider, AutoCloseable { // Start RPC Service this.rpcApiService = new DataProviderServiceImpl(rpcProviderService, this.mediatorServerServlet); this.treeServlet.setDatabaseClient(this.rpcApiService.getRawClient()); + this.userdataServlet.setDatabaseClient(this.rpcApiService.getHtDatabaseUserManager()); LOG.info("Session Initiated end. Initialization done"); } catch (Exception e) { if (e instanceof HtDatabaseClientException) @@ -144,4 +150,9 @@ public class DataProviderImpl implements IEntityDataProvider, AutoCloseable { } } + @Override + public HtUserdataManager getHtDatabaseUserManager() { + return this.rpcApiService.getHtDatabaseUserManager(); + } + } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java index 5ef7a0ad9..9e7fc18bc 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataProviderServiceImpl.java @@ -30,10 +30,12 @@ import org.eclipse.jdt.annotation.NonNull; import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.ElasticSearchDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.HtUserdataManagerImpl; import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.MediatorServerDataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.MsServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtDatabaseMaintenance; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEsConfig; import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInput; @@ -107,6 +109,7 @@ public class DataProviderServiceImpl implements DataProviderService, AutoCloseab private final ConfigurationFileRepresentation configuration; private final EsConfig esConfig; private final MediatorServerDataProvider mediatorServerDataProvider; + private final HtUserdataManager dbUserManager; DataProviderServiceImpl(final RpcProviderService rpcProviderService, MsServlet mediatorServerServlet) throws Exception { @@ -118,6 +121,7 @@ public class DataProviderServiceImpl implements DataProviderService, AutoCloseab this.mediatorServerDataProvider = new MediatorServerDataProvider(esConfig.getHosts(), esConfig.getBasicAuthUsername(), esConfig.getBasicAuthPassword(),esConfig.trustAllCerts()); mediatorServerServlet.setDataProvider(this.mediatorServerDataProvider); + this.dbUserManager = new HtUserdataManagerImpl(this.dataProvider.getRawClient()); // Register ourselves as the REST API RPC implementation LOG.info("Register RPC Service " + DataProviderServiceImpl.class.getSimpleName()); this.rpcReg = rpcProviderService.registerRpcImplementation(DataProviderService.class, this); @@ -412,4 +416,8 @@ public class DataProviderServiceImpl implements DataProviderService, AutoCloseab return result; } + public HtUserdataManager getHtDatabaseUserManager() { + return this.dbUserManager; + } + } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataTreeProviderImpl.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataTreeProviderImpl.java index 4340d8168..e69ddb737 100644 --- a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataTreeProviderImpl.java +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/impl/DataTreeProviderImpl.java @@ -36,7 +36,6 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.requests.SearchRequest; import org.onap.ccsdk.features.sdnr.wt.common.database.responses.AggregationEntries; import org.onap.ccsdk.features.sdnr.wt.common.database.responses.SearchResponse; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeChildObject; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeHttpServlet.FilterMode; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeObject; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Entity; @@ -48,12 +47,12 @@ public class DataTreeProviderImpl { private static final long MAXSIZE_PERSEARCH = 10; private HtDatabaseClient dbClient; - final String INVENTORY_PROPERTY_TREELEVEL = "tree-level"; - final String INVENTORY_PROPERTY_NODEID = "node-id"; - final String INVENTORY_PROPERTY_UUID = "uuid"; - final String INVENTORY_PROPERTY_PARENTUUID = "parent-uuid"; - final String INVENTORY_PROPERTY_FOR_LABEL_CHILD = "uuid"; - final String INVENTORY_PROPERTY_FOR_LABEL = "uuid"; + private static final String INVENTORY_PROPERTY_TREELEVEL = "tree-level"; + private static final String INVENTORY_PROPERTY_NODEID = "node-id"; + private static final String INVENTORY_PROPERTY_UUID = "uuid"; + private static final String INVENTORY_PROPERTY_PARENTUUID = "parent-uuid"; + private static final String INVENTORY_PROPERTY_FOR_LABEL_CHILD = "uuid"; + private static final String INVENTORY_PROPERTY_FOR_LABEL = "uuid"; private List<SearchHit> search(Entity e, String filter, String propTreeLevel) throws IOException { return this.search(e, filter, null, null, null, null, null, null, propTreeLevel); @@ -132,15 +131,15 @@ public class DataTreeProviderImpl { * @return * @throws IOException */ - public DataTreeObject readInventoryTree(List<String> tree, String filter, FilterMode mode) throws IOException { + public DataTreeObject readInventoryTree(List<String> tree, String filter) throws IOException { //root nodes will be node-information -> below inventory if (tree == null || tree.size() <= 0) { - return this.readInventoryTreeWithNode(filter, mode); + return this.readInventoryTreeWithNode(filter); } //root node will be inventory on tree-level if sliced treePath else { - return this.readInventoryTreeForNode(tree.get(0), tree.subList(0, tree.size() - 1), filter, mode); + return this.readInventoryTreeForNode(tree.get(0), tree.subList(0, tree.size() - 1), filter); } } @@ -152,7 +151,7 @@ public class DataTreeProviderImpl { * @param mode * @return */ - private DataTreeObject readInventoryTreeForNode(String nodeId, List<String> list, String filter, FilterMode mode) + private DataTreeObject readInventoryTreeForNode(String nodeId, List<String> list, String filter) throws IOException { DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID); final String parentUuid = list.size() > 1 ? list.get(list.size() - 2) : null; @@ -161,7 +160,8 @@ public class DataTreeProviderImpl { INVENTORY_PROPERTY_PARENTUUID, parentUuid, INVENTORY_PROPERTY_UUID, uuid, INVENTORY_PROPERTY_TREELEVEL); //tree.a(subtreePath); - List<SearchHit> others = this.search(Entity.Inventoryequipment, (String) null, INVENTORY_PROPERTY_TREELEVEL); + List<SearchHit> others = this.search(Entity.Inventoryequipment, (String) null, INVENTORY_PROPERTY_NODEID, nodeId, + null, null, null, null, INVENTORY_PROPERTY_TREELEVEL); if (matches.size() > 0) { int treeLevelToStart = (list == null || list.size() <= 0) ? 0 : list.size() - 1; //build tree @@ -208,6 +208,7 @@ public class DataTreeProviderImpl { hitData.getString(INVENTORY_PROPERTY_PARENTUUID))); } } + tree.removeUnmatchedPaths(); } return tree; } @@ -216,11 +217,10 @@ public class DataTreeProviderImpl { * node will be root elements inventory information below from level-1 * * @param filter - * @param mode * @return * @throws IOException */ - private DataTreeObject readInventoryTreeWithNode(String filter, FilterMode mode) throws IOException { + private DataTreeObject readInventoryTreeWithNode(String filter) throws IOException { DataTreeObject tree = new DataTreeObject(INVENTORY_PROPERTY_PARENTUUID, INVENTORY_PROPERTY_UUID); List<SearchHit> matches = this.search(Entity.Inventoryequipment, filter, INVENTORY_PROPERTY_TREELEVEL); @@ -302,9 +302,8 @@ public class DataTreeProviderImpl { } } } - if (mode == FilterMode.Strict) { - tree.removeUnmatchedPaths(); - } + tree.removeUnmatchedPaths(); + } return tree; } diff --git a/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/DataProviderYangToolsMapper.java b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/DataProviderYangToolsMapper.java new file mode 100644 index 000000000..78b032e77 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/yangtools/DataProviderYangToolsMapper.java @@ -0,0 +1,50 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools; + +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.serialize.IdentifierDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.pmdata.grp.MeasurementKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * YangToolsMapper is a specific Jackson mapper configuration for opendaylight yangtools serialization or + * deserialization of DataObject to/from JSON TODO ChoiceIn and Credentials deserialization only for + * LoginPasswordBuilder + */ +public class DataProviderYangToolsMapper extends YangToolsMapper { + + @SuppressWarnings("unused") + private final Logger LOG = LoggerFactory.getLogger(DataProviderYangToolsMapper.class); + private static final long serialVersionUID = 1L; + + public DataProviderYangToolsMapper() { + super(); + this.addDeserializer(Credentials.class, LoginPasswordBuilder.class.getName()); + this.addKeyDeserializer(MeasurementKey.class, new IdentifierDeserializer()); + } + + +} diff --git a/sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml b/sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml index ebb20fc7b..686af61d6 100644 --- a/sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml +++ b/sdnr/wt/data-provider/provider/src/main/resources/org/opendaylight/blueprint/impl-blueprint.xml @@ -70,6 +70,15 @@ </service-properties> </service> + <bean id="userdataServlet" + class="org.onap.ccsdk.features.sdnr.wt.dataprovider.http.UserdataHttpServlet"> + </bean> + <service interface="javax.servlet.http.HttpServlet" ref="userdataServlet"> + <service-properties> + <entry key="alias" value="/userdata"/> + </service-properties> + </service> + <bean id="provider" class="org.onap.ccsdk.features.sdnr.wt.dataprovider.impl.DataProviderImpl" init-method="init" destroy-method="close"> @@ -77,6 +86,7 @@ <property name="aboutServlet" ref="aboutServlet"/> <property name="treeServlet" ref="treeServlet"/> <property name="mediatorServerServlet" ref="msServlet"/> + <property name="userdataServlet" ref="userdataServlet"/> </bean> <bean id="yangServlet" diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestCRUDforDatabase.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestCRUDforDatabase.java index b7a4db51b..5a8c549d8 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestCRUDforDatabase.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestCRUDforDatabase.java @@ -40,9 +40,11 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo; import org.onap.ccsdk.features.sdnr.wt.common.database.queries.QueryBuilders; import org.onap.ccsdk.features.sdnr.wt.common.database.requests.BaseRequest; import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.ElasticSearchDataProvider; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.HtUserdataManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.UserdataHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.YangHelper2; import org.onap.ccsdk.features.sdnr.wt.dataprovider.test.util.HostInfoForTest; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.DataProviderYangToolsMapper; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.CreateMaintenanceInputBuilder; @@ -227,7 +229,8 @@ public class TestCRUDforDatabase { // ==READ=========================== System.out.println("try to read entry"); ReadMediatorServerListInput readinput = new ReadMediatorServerListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class,new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadMediatorServerListOutputBuilder readoutput = dbProvider.readMediatorServerList(readinput); List<Data> data = readoutput.getData(); @@ -254,7 +257,8 @@ public class TestCRUDforDatabase { // ==READ============================ System.out.println("try to read entry"); readinput = new ReadMediatorServerListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("name").setFiltervalue(NAME2).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("name").setFiltervalue(NAME2).build())) .setPagination(getPagination(20, 1)).build(); readoutput = dbProvider.readMediatorServerList(readinput); data = readoutput.getData(); @@ -277,7 +281,8 @@ public class TestCRUDforDatabase { // ==READ/VERIFY DELETE============================ System.out.println("try to read entry"); readinput = new ReadMediatorServerListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("name").setFiltervalue(NAME2).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("name").setFiltervalue(NAME2).build())) .setPagination(getPagination(20, 1)).build(); readoutput = dbProvider.readMediatorServerList(readinput); data = readoutput.getData(); @@ -322,7 +327,8 @@ public class TestCRUDforDatabase { // ==READ=========================== ReadNetworkElementConnectionListInput readInput = new ReadNetworkElementConnectionListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadNetworkElementConnectionListOutputBuilder readOperation = @@ -393,7 +399,8 @@ public class TestCRUDforDatabase { } readInput = new ReadNetworkElementConnectionListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); readOperation = dbProvider.readNetworkElementConnectionList(readInput); data = readOperation.getData(); @@ -437,7 +444,8 @@ public class TestCRUDforDatabase { System.out.println("Try read..."); ReadMaintenanceListInput readinput = new ReadMaintenanceListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadMaintenanceListOutputBuilder readResult = dbProvider.readMaintenanceList(readinput); List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.maintenance.list.output.Data> data = @@ -502,7 +510,8 @@ public class TestCRUDforDatabase { System.out.println("try to read entry"); ReadFaultlogListInput readinput = new ReadFaultlogListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadFaultlogListOutputBuilder readResult = null; @@ -530,7 +539,8 @@ public class TestCRUDforDatabase { System.out.println("try to search entry 1"); readinput = new ReadFaultlogListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("node-id").setFiltervalue("test").build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("node-id").setFiltervalue("test").build())) .setPagination(getPagination(20, 1)).build(); //== VERIFY UPDATE ================================ @@ -545,7 +555,8 @@ public class TestCRUDforDatabase { System.out.println("try to search entry 2"); readinput = new ReadFaultlogListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("node-id").setFiltervalue("test*").build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("node-id").setFiltervalue("test*").build())) .setPagination(getPagination(20, 1)).build(); readResult = dbProvider.readFaultLogList(readinput); @@ -589,7 +600,8 @@ public class TestCRUDforDatabase { ReadFaultcurrentListInput readinput = new ReadFaultcurrentListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadFaultcurrentListOutputBuilder readResult = null; @@ -693,7 +705,8 @@ public class TestCRUDforDatabase { System.out.println("Try read entry"); ReadConnectionlogListInput readinput = new ReadConnectionlogListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadConnectionlogListOutputBuilder readResult = null; @@ -722,7 +735,8 @@ public class TestCRUDforDatabase { System.out.println("Try read updated entry"); readinput = new ReadConnectionlogListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("status").setFiltervalue("Connected").build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("status").setFiltervalue("Connected").build())) .setPagination(getPagination(20, 1)).build(); try { @@ -782,7 +796,8 @@ public class TestCRUDforDatabase { // ==READ=========================== ReadEventlogListInput readinput = new ReadEventlogListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadEventlogListOutputBuilder readResult = null; try { @@ -850,7 +865,8 @@ public class TestCRUDforDatabase { // ==READ=========================== ReadInventoryListInput readinput = new ReadInventoryListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("id").setFiltervalue(dbId).build())) .setPagination(getPagination(20, 1)).build(); ReadInventoryListOutputBuilder readResult = null; try { @@ -1015,7 +1031,8 @@ public class TestCRUDforDatabase { System.out.println("read list entries..."); ReadPmdata15mListInput read = new ReadPmdata15mListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) .setPagination(getPagination(20, 1)).build(); ReadPmdata15mListOutputBuilder readResult = null; @@ -1035,7 +1052,8 @@ public class TestCRUDforDatabase { System.out.println("read ltp entries with node name set..."); ReadPmdata15mLtpListInput readLtp = new ReadPmdata15mLtpListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) .setPagination(getPagination(20, 1)).build(); ReadPmdata15mLtpListOutputBuilder readltpResult = null; @@ -1133,7 +1151,8 @@ public class TestCRUDforDatabase { System.out.println("filter list entries..."); read = new ReadPmdata24hListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) .setPagination(getPagination(20, 1)).build(); readResult = null; @@ -1152,7 +1171,8 @@ public class TestCRUDforDatabase { System.out.println("read ltp entries with node name set..."); ReadPmdata24hLtpListInput readLtp = new ReadPmdata24hLtpListInputBuilder() - .setFilter(YangHelper2.getListOrMap(FilterKey.class, new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) + .setFilter(YangHelper2.getListOrMap(FilterKey.class, + new FilterBuilder().setProperty("node-name").setFiltervalue("a2").build())) .setPagination(getPagination(20, 1)).build(); ReadPmdata24hLtpListOutputBuilder readltpResult = null; @@ -1363,7 +1383,7 @@ public class TestCRUDforDatabase { + "\"implemented-interface\": \"org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Faultlog\",\n" + "\"source-type\": \"Netconf\",\n" + "\"node-id\": \"sim4\",\n" + "\"problem\": \"signalIsLost\"\n" + "}"; - YangToolsMapper yangtoolsMapper = new YangToolsMapper(); + DataProviderYangToolsMapper yangtoolsMapper = new DataProviderYangToolsMapper(); Faultlog log = yangtoolsMapper.readValue(jsonString, Faultlog.class); System.out.println(yangtoolsMapper.writeValueAsString((new FaultlogBuilder(log).build()))); System.out.println("Check3"); @@ -1374,6 +1394,27 @@ public class TestCRUDforDatabase { } + @Test + public void testUserdata() { + final String USERNAME = "admin"; + final String DATA1 = "{\n" + " \"networkMap\":{\n" + + " \"startupPosition\": {\"lat\": 52.5095, \"lon\":13.329, \"zoom\": 10},\n" + + " \"tileOpacity\": 90,\n" + " \"styling\":{\n" + " \"theme\": \"light\"\n" + + " }\n" + " },\n" + " \"dashboard\":{\n" + " \"color\":\"#F00\"\n" + " }\n" + + "}"; + HtUserdataManagerImpl client = new HtUserdataManagerImpl(dbRawProvider); + boolean success = client.setUserdata(USERNAME, DATA1); + assertTrue(success); + String data = client.getUserdata(USERNAME); + //JSONAssert.assertEquals(DATA1,data,false); + + assertEquals("admin", UserdataHttpServlet.decodeJWTPayloadUsername(String.format("Bearer %s", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbkBzZG4iLCJyb2xlcyI6WyJ1c2VyIiwiYWRtaW4iXSwiaXN" + + "zIjoiT3BlbmRheWxpZ2h0IiwibmFtZSI6ImFkbWluQHNkbiIsImV4cCI6MTYxNTc5NTg1NywiZmFtaWx5X25hbWUiOiIifQ.wB" + + "PdB45_bryU6_kSCu3be3dq3yth24niSXi6b2_1ufc"), + "sub")); + } + private Pagination getPagination(long pageSize, int page) { return new PaginationBuilder().setPage(YangHelper2.getBigIntegerOrUint64(BigInteger.valueOf(page))) .setSize(YangHelper2.getLongOrUint32(pageSize)).build(); diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestDataMappings.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestDataMappings.java index eaaa31107..56bc32ce3 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestDataMappings.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestDataMappings.java @@ -24,7 +24,7 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.test; import static org.junit.Assert.fail; import java.io.IOException; import org.junit.Test; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper2; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapper2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.read.pmdata._15m.list.output.Data; public class TestDataMappings { diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestEventService.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestEventService.java index 7e63c183c..56138b0b1 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestEventService.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestEventService.java @@ -63,6 +63,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.PmdataEntityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SourceType; +import org.opendaylight.yangtools.yang.common.Uint32; /** * @author Michael Dürre @@ -205,6 +206,7 @@ public class TestEventService { List<NetworkElementConnectionEntity> nes = service.getNetworkElementConnections(); assertEquals(0, nes.size()); service.updateNetworkConnection22(createNeConnection(NODEID, NetworkElementDeviceType.Unknown), NODEID); + service.updateNetworkConnection22(createNeConnection(NODEID, NetworkElementDeviceType.Unknown), NODEID); service.updateNetworkConnection22(createNeConnection(NODEID2, NetworkElementDeviceType.ORAN), NODEID2); nes = service.getNetworkElementConnections(); assertEquals(2, nes.size()); @@ -243,11 +245,9 @@ public class TestEventService { @Test public void testInventory() { clearDbEntity(Entity.Inventoryequipment); - service.writeInventory(createEquipment(NODEID, "uuid1")); - service.writeInventory(createEquipment(NODEID, "uuid2")); - service.writeInventory(createEquipment(NODEID2, "uuid3")); - service.writeInventory(createEquipment(NODEID2, "uuid4")); - service.writeInventory(createEquipment(NODEID2, "uuid5")); + service.writeInventory(NODEID,Arrays.asList(createEquipment(NODEID, "uuid1"), createEquipment(NODEID, "uuid2"), + createEquipment(NODEID, "uuid3"), createEquipment(NODEID, "uuid4"), + createEquipment(NODEID, "uuid5"))); assertEquals(5, getDbEntityEntries(Entity.Inventoryequipment).getTotal()); } @@ -272,19 +272,21 @@ public class TestEventService { * @return */ private Inventory createEquipment(String nodeId, String uuid) { - return new InventoryBuilder().setNodeId(nodeId).setParentUuid("").setDescription("desc") - .setManufacturerName("manu").setDate(NetconfTimeStampImpl.getConverter().getTimeStampAsNetconfString()).setUuid(uuid).build(); + return new InventoryBuilder().setNodeId(nodeId).setParentUuid(null).setDescription("desc") + .setTreeLevel(Uint32.valueOf(0)).setManufacturerName("manu") + .setDate(NetconfTimeStampImpl.getConverter().getTimeStampAsNetconfString()).setUuid(uuid).build(); } /** * @param devType + * @param mountMethod * @param nodename3 * @return */ private static NetworkElementConnectionEntity createNeConnection(String nodeId, NetworkElementDeviceType devType) { - return new NetworkElementConnectionBuilder().setNodeId(nodeId).setHost("host").setPort(YangHelper2.getLongOrUint32(1234L)) - .setCoreModelCapability("123").setStatus(ConnectionLogStatus.Connected).setDeviceType(devType) - .setIsRequired(true).build(); + return new NetworkElementConnectionBuilder().setNodeId(nodeId).setHost("host") + .setPort(YangHelper2.getLongOrUint32(1234L)).setCoreModelCapability("123") + .setStatus(ConnectionLogStatus.Connected).setDeviceType(devType).setIsRequired(true).build(); } /** diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestImplementation.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestImplementation.java index aa010939d..16dfa0ec6 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestImplementation.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestImplementation.java @@ -22,14 +22,13 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.test; import static org.junit.Assert.fail; - import java.util.Set; - import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes.Section; import org.onap.ccsdk.features.sdnr.wt.common.configuration.subtypes.Section.EnvGetter; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.MsServlet; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.UserdataHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.about.AboutHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.impl.DataProviderImpl; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.StatusChangedHandler.StatusKey; @@ -73,6 +72,7 @@ public class TestImplementation { impl.setMediatorServerServlet(new MsServlet()); impl.setAboutServlet(new AboutHttpServlet()); impl.setTreeServlet(new DataTreeHttpServlet()); + impl.setUserdataServlet(new UserdataHttpServlet()); try { impl.init(); } catch (Exception e) { diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestNuMappings.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestNuMappings.java index 76286c820..b52e34c49 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestNuMappings.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestNuMappings.java @@ -24,7 +24,7 @@ package org.onap.ccsdk.features.sdnr.wt.dataprovider.test; import static org.junit.Assert.assertTrue; import java.io.IOException; import org.junit.Test; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.DataProviderYangToolsMapper; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Faultcurrent; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; @@ -33,7 +33,7 @@ public class TestNuMappings { @Test public void testMapObjectToJson() throws IOException { - YangToolsMapper mapper = new YangToolsMapper(); + DataProviderYangToolsMapper mapper = new DataProviderYangToolsMapper(); Faultcurrent c = new FaultcurrentBuilder().setSeverity(SeverityType.Critical).build(); String json = mapper.writeValueAsString(c); @@ -42,7 +42,7 @@ public class TestNuMappings { @Test public void testMapJsonToObject() throws IOException { - YangToolsMapper mapper = new YangToolsMapper(); + DataProviderYangToolsMapper mapper = new DataProviderYangToolsMapper(); Faultcurrent f = mapper.readValue("{\"severity\":\"Critical\"}", Faultcurrent.class); assertTrue("Critical expected", f.getSeverity().equals(SeverityType.Critical)); diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTree.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTree.java index 53c72115d..e32179122 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTree.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestTree.java @@ -36,7 +36,6 @@ import org.onap.ccsdk.features.sdnr.wt.common.test.JSONAssert; import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.ElasticSearchDataProvider; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeHttpServlet; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeHttpServlet.EntityWithTree; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeHttpServlet.FilterMode; import org.onap.ccsdk.features.sdnr.wt.dataprovider.http.DataTreeObject; import org.onap.ccsdk.features.sdnr.wt.dataprovider.impl.DataTreeProviderImpl; import org.onap.ccsdk.features.sdnr.wt.dataprovider.test.util.HostInfoForTest; @@ -91,14 +90,14 @@ public class TestTree { provider.setDatabaseClient(dbRawProvider); - DataTreeObject tree = provider.readInventoryTree(null, null, FilterMode.Lazy); + DataTreeObject tree = provider.readInventoryTree(null, null); System.out.println(tree.toJSON()); JSONObject o = new JSONObject(tree.toJSON()); JSONAssert.assertContainsOnlyKey(o, "sim1"); JSONObject children = o.getJSONObject("sim1").getJSONObject("children"); this.assertSim1(children); - tree = provider.readInventoryTree(Arrays.asList("sim1"), "*", FilterMode.Lazy); + tree = provider.readInventoryTree(Arrays.asList("sim1"), "*"); this.assertSim1(new JSONObject(tree.toJSON())); System.out.println(tree.toJSON()); diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestUserdata.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestUserdata.java new file mode 100644 index 000000000..fd397840e --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestUserdata.java @@ -0,0 +1,94 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.dataprovider.test; + +import static org.junit.Assert.fail; +import java.io.IOException; +import org.apache.sshd.common.util.io.IoUtils; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.common.database.HtDatabaseClient; +import org.onap.ccsdk.features.sdnr.wt.common.database.config.HostInfo; +import org.onap.ccsdk.features.sdnr.wt.common.test.JSONAssert; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.HtUserdataManagerImpl; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.test.util.HostInfoForTest; + +public class TestUserdata { + + private static final String USERNAME = "admin"; + private static HtDatabaseClient dbRawProvider; + private static HtUserdataManagerImpl userDbProvider; + + @BeforeClass + public static void init() throws Exception { + + HostInfo[] hosts = HostInfoForTest.get(); + dbRawProvider = HtDatabaseClient.getClient(hosts); + userDbProvider = new HtUserdataManagerImpl(dbRawProvider); + } + + public static void trySleep(long ms) { + try { + Thread.sleep(ms); + } catch (Exception e) { + Thread.currentThread().interrupt(); + } + } + + @Ignore + @Test + public void test1() { + String fullContent = ""; + try { + fullContent = getFileContent("/userdata/full.json"); + userDbProvider.setUserdata(USERNAME, fullContent); + } catch (IOException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + + trySleep(2000); + + String userdata = userDbProvider.getUserdata(USERNAME); + JSONAssert.assertEquals(fullContent, userdata, false); + String networkMapContent = ""; + String mergedContent = ""; + try { + networkMapContent = getFileContent("/userdata/networkmap.json"); + mergedContent = getFileContent("/userdata/merged.json"); + userDbProvider.setUserdata(USERNAME, "networkMap", networkMapContent); + } catch (IOException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + + trySleep(2000); + + userdata = userDbProvider.getUserdata(USERNAME); + JSONAssert.assertEquals(mergedContent, userdata, false); + } + + private static String getFileContent(String filename) throws IOException { + return String.join("\n", IoUtils.readAllLines(TestTree.class.getResourceAsStream(filename))); + } +} diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMapping.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMapping.java index 3c9d4946b..524659e99 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMapping.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMapping.java @@ -40,8 +40,8 @@ import org.onap.ccsdk.features.sdnr.wt.common.database.requests.DeleteIndexReque import org.onap.ccsdk.features.sdnr.wt.dataprovider.database.EsDataObjectReaderWriter2; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.YangHelper2; import org.onap.ccsdk.features.sdnr.wt.dataprovider.test.util.HostInfoForTest; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.DataProviderYangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapperHelper; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; @@ -65,7 +65,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.pro public class TestYangGenSalMapping { // Create mapper for serialization and deserialization - YangToolsMapper mapper = new YangToolsMapper(); + DataProviderYangToolsMapper mapper = new DataProviderYangToolsMapper(); @Test public void test1() throws IOException { diff --git a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMappingOpenRoadm.java b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMappingOpenRoadm.java index 56df62819..1345d4edf 100644 --- a/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMappingOpenRoadm.java +++ b/sdnr/wt/data-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/dataprovider/test/TestYangGenSalMappingOpenRoadm.java @@ -32,8 +32,8 @@ import org.jline.utils.Log; import org.junit.Test; import org.mockito.Mockito; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.types.YangHelper2; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapper2; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.DataProviderYangToolsMapper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.YangToolsMapper2; import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev191129.PmDataType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.openroadm.pm.types.rev200413.BIPErrorCounter; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.openroadm.pm.types.rev200413.OpticalPowerInputOSCMin; @@ -74,7 +74,7 @@ public class TestYangGenSalMappingOpenRoadm extends Mockito { PmdataEntity pmDataType = pmDataEntitybuilder.build(); - YangToolsMapper mapper2 = new YangToolsMapper(); + DataProviderYangToolsMapper mapper2 = new DataProviderYangToolsMapper(); String jsonString = mapper2.writeValueAsString(pmDataType); out("Result json after mapping: " + jsonString); @@ -88,7 +88,7 @@ public class TestYangGenSalMappingOpenRoadm extends Mockito { public void testOpenroadmPMString1() throws IOException, ClassNotFoundException { out("Test: " + method()); String jsonString2 = getFileContent("pmdata1.json"); - YangToolsMapper mapper2 = new YangToolsMapper(); + DataProviderYangToolsMapper mapper2 = new DataProviderYangToolsMapper(); PmdataEntity generatepmdNode = mapper2.readValue(jsonString2.getBytes(), PmdataEntity.class); out("String1:"+generatepmdNode.toString()); // Print it with specified indentation assertTrue("GranularityPeriod", generatepmdNode.getGranularityPeriod().equals(GranularityPeriodType.Period15Min)); @@ -105,7 +105,7 @@ public class TestYangGenSalMappingOpenRoadm extends Mockito { public void testOpenroadmPMString2() throws IOException, ClassNotFoundException { out("Test: " + method()); String jsonString2 = getFileContent("pmdata2.json"); - YangToolsMapper mapper2 = new YangToolsMapper(); + DataProviderYangToolsMapper mapper2 = new DataProviderYangToolsMapper(); PmdataEntity generatepmdNode = mapper2.readValue(jsonString2.getBytes(), PmdataEntity.class); out(generatepmdNode.toString()); // Print it with specified indentation } diff --git a/sdnr/wt/data-provider/provider/src/test/resources/userdata/full.json b/sdnr/wt/data-provider/provider/src/test/resources/userdata/full.json new file mode 100644 index 000000000..c5b41ec21 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/resources/userdata/full.json @@ -0,0 +1,13 @@ +{ + "networkMap": { + "styling": { + "theme": "dark" + }, + "startupPosition": { + "latitude": "52.5", + "zoom": "10", + "longitude": "13.35" + }, + "tileOpacity": "26" + } +}
\ No newline at end of file diff --git a/sdnr/wt/data-provider/provider/src/test/resources/userdata/merged.json b/sdnr/wt/data-provider/provider/src/test/resources/userdata/merged.json new file mode 100644 index 000000000..4e283cd6f --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/resources/userdata/merged.json @@ -0,0 +1,13 @@ +{ + "networkMap": { + "tileOpacity": "26", + "styling": { + "theme": "light" + }, + "startupPosition": { + "latitude": "52.5", + "longitude": "13.35", + "zoom": "10" + } + } +}
\ No newline at end of file diff --git a/sdnr/wt/data-provider/provider/src/test/resources/userdata/networkmap.json b/sdnr/wt/data-provider/provider/src/test/resources/userdata/networkmap.json new file mode 100644 index 000000000..20d44f752 --- /dev/null +++ b/sdnr/wt/data-provider/provider/src/test/resources/userdata/networkmap.json @@ -0,0 +1,11 @@ +{ + "tileOpacity": "26", + "styling": { + "theme": "light" + }, + "startupPosition": { + "latitude": "52.5", + "longitude": "13.35", + "zoom": "10" + } +}
\ No newline at end of file diff --git a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElement.java b/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElement.java index 0fa83c031..203c06134 100644 --- a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElement.java +++ b/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElement.java @@ -20,7 +20,6 @@ package org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.Optional; @@ -29,18 +28,18 @@ import org.junit.BeforeClass; import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.impl.AdapterManagerNetworkElementFactory; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.test.mock.NetconfAccessorMock; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.test.mock.TransactionUtilsMock; import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; import org.opendaylight.yang.gen.v1.urn.onf.params.xml.ns.yang.network.topology.simulator.rev191025.SimulatorStatus; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.yang.common.QName; public class TestAdapterManagerNetworkElement { - static NetconfAccessorMock accessor; + static NetconfBindingAccessor accessor; static DeviceManagerServiceProvider serviceProvider; static Capabilities capabilities; QName qCapability; @@ -49,13 +48,13 @@ public class TestAdapterManagerNetworkElement { public static void init() throws InterruptedException, IOException { capabilities = mock(Capabilities.class); //accessor = mock(NetconfAccessorMock.class); - accessor = spy(new NetconfAccessorMock(null, null, null, null)); + accessor = mock(NetconfBindingAccessor.class); //accessor = spy(new NetconfAccessorMock(null, null, null, null)); serviceProvider = mock(DeviceManagerServiceProvider.class); NodeId nNodeId = new NodeId("nSky"); when(accessor.getCapabilites()).thenReturn(capabilities); when(accessor.getNodeId()).thenReturn(nNodeId); - when(accessor.getTransactionUtils()).thenReturn(new TransactionUtilsMock()); + when(accessor.getTransactionUtils()).thenReturn(mock(TransactionUtils.class)); DataProvider dataProvider = mock(DataProvider.class); when(serviceProvider.getDataProvider()).thenReturn(dataProvider); diff --git a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElementFactory.java b/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElementFactory.java index 228401d6e..ad024e10e 100644 --- a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElementFactory.java +++ b/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/TestAdapterManagerNetworkElementFactory.java @@ -25,7 +25,6 @@ import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.impl.AdapterManagerNetworkElementFactory; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.test.mock.NetconfAccessorMock; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; @@ -42,7 +41,7 @@ public class TestAdapterManagerNetworkElementFactory { @BeforeClass public static void init() throws InterruptedException, IOException { capabilities = mock(Capabilities.class); - accessor = mock(NetconfAccessorMock.class); + accessor = mock(NetconfAccessor.class); serviceProvider = mock(DeviceManagerServiceProvider.class); when(accessor.getCapabilites()).thenReturn(capabilities); diff --git a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/mock/NetconfAccessorMock.java b/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/mock/NetconfAccessorMock.java deleted file mode 100644 index 8a0694087..000000000 --- a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/mock/NetconfAccessorMock.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * 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. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.test.mock; - -import com.google.common.util.concurrent.ListenableFuture; -import java.util.List; -import java.util.Optional; - -import org.eclipse.jdt.annotation.NonNull; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNotifications; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; -import org.opendaylight.mdsal.binding.api.DataBroker; -import org.opendaylight.mdsal.binding.api.MountPoint; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionOutput; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.NotificationListener; -import org.opendaylight.yangtools.yang.common.RpcResult; - -/** - */ -public class NetconfAccessorMock implements NetconfBindingAccessor, NetconfNotifications { - - private final NodeId nNodeId; - private final NetconfNode netconfNode; - private final MountPoint mountpoint; - private final DataBroker netconfNodeDataBroker; - - public NetconfAccessorMock(NodeId nNodeId, NetconfNode netconfNode, MountPoint mountpoint, - DataBroker netconfNodeDataBroker) { - this.nNodeId = nNodeId; - this.netconfNode = netconfNode; - this.mountpoint = mountpoint; - this.netconfNodeDataBroker = netconfNodeDataBroker; - } - - @Override - public NodeId getNodeId() { - return nNodeId; - } - - @Override - public NetconfNode getNetconfNode() { - return netconfNode; - } - - @Override - public Capabilities getCapabilites() { - return null; - } - - @Override - public DataBroker getDataBroker() { - return netconfNodeDataBroker; - } - - @Override - public MountPoint getMountpoint() { - return mountpoint; - } - - @Override - public TransactionUtils getTransactionUtils() { - return null; - } - - @Override - public <T extends NotificationListener> ListenerRegistration<NotificationListener> doRegisterNotificationListener( - @NonNull T listener) { - return null; - } - - @Override - public ListenableFuture<RpcResult<CreateSubscriptionOutput>> registerNotificationsStream(String streamName) { - return null; - } - - @Override - public void registerNotificationsStream(List<Stream> streamList) { - // TODO Auto-generated method stub - - } - - @Override - public boolean isNCNotificationsSupported() { - // TODO Auto-generated method stub - return false; - } - - @Override - public List<Stream> getNotificationStreams() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Optional<NetconfBindingAccessor> getNetconfBindingAccessor() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Optional<NetconfDomAccessor> getNetconfDomAccessor() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Optional<NetconfNotifications> getNotificationAccessor() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isNotificationsSupported() { - // TODO Auto-generated method stub - return false; - } - -} diff --git a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/mock/TransactionUtilsMock.java b/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/mock/TransactionUtilsMock.java deleted file mode 100644 index e3aa0ae43..000000000 --- a/sdnr/wt/devicemanager-adapter-manager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/adaptermanager/test/mock/TransactionUtilsMock.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * 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. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.adaptermanager.test.mock; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import org.eclipse.jdt.annotation.Nullable; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; -import org.opendaylight.mdsal.binding.api.DataBroker; -import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class TransactionUtilsMock implements TransactionUtils { - - @Override - public <T extends DataObject> @Nullable T readData(DataBroker dataBroker, LogicalDatastoreType dataStoreType, - InstanceIdentifier<T> iid) { - // TODO Auto-generated method stub - return null; - } - - @Override - public <T extends DataObject> @Nullable T readDataOptionalWithStatus(DataBroker dataBroker, - LogicalDatastoreType dataStoreType, InstanceIdentifier<T> iid, AtomicBoolean noErrorIndication, - AtomicReference<String> statusIndicator) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/sdnr/wt/devicemanager-oran/provider/pom.xml b/sdnr/wt/devicemanager-oran/provider/pom.xml index b63957986..e6ae4bfc2 100644 --- a/sdnr/wt/devicemanager-oran/provider/pom.xml +++ b/sdnr/wt/devicemanager-oran/provider/pom.xml @@ -60,6 +60,11 @@ <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + <scope>test</scope> + </dependency> <!-- end for testing --> <dependency> @@ -86,6 +91,11 @@ <scope>provided</scope> </dependency> <dependency> + <groupId>org.opendaylight.netconf</groupId> + <artifactId>callhome-model</artifactId> + <!-- <scope>provided</scope> --> + </dependency> + <dependency> <groupId>org.opendaylight.mdsal</groupId> <artifactId>mdsal-singleton-common-api</artifactId> <scope>provided</scope> diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java index baa86b4c7..63d8f2787 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanChangeNotificationListener.java @@ -17,11 +17,13 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; -import java.time.Instant; -import java.util.HashMap; +import com.fasterxml.jackson.core.JsonProcessingException; import java.util.List; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.IetfNetconfNotificationsListener; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange; @@ -46,13 +48,17 @@ public class ORanChangeNotificationListener implements IetfNetconfNotificationsL private final NetconfBindingAccessor netconfAccessor; private final DataProvider databaseService; private final VESCollectorService vesCollectorService; + private final NotificationProxyParser notificationProxyParser; + private ORanNotifToVESEventAssembly mapper = null; private static int sequenceNo = 0; - public ORanChangeNotificationListener(NetconfBindingAccessor netconfAccessor, DataProvider databaseService, VESCollectorService vesCollectorService) { + public ORanChangeNotificationListener(NetconfBindingAccessor netconfAccessor, DataProvider databaseService, + VESCollectorService vesCollectorService, NotificationProxyParser notificationProxyParser) { this.netconfAccessor = netconfAccessor; this.databaseService = databaseService; this.vesCollectorService = vesCollectorService; + this.notificationProxyParser = notificationProxyParser; } @Override @@ -102,17 +108,23 @@ public class ORanChangeNotificationListener implements IetfNetconfNotificationsL databaseService.writeEventLog(eventlogBuilder.build()); } log.info("onNetconfConfigChange (2) {}", sb); - ORanNotificationMapper mapper = new ORanNotificationMapper(); - HashMap<String, String> xPathFieldsMap = mapper.performMapping(notification); - log.info("MappingInfo after mapping notification - {}", xPathFieldsMap); - Instant instant = mapper.getTime(notification); - ORanNotifToVESEventAssembly oranVESEventAssembly = new ORanNotifToVESEventAssembly(netconfAccessor, vesCollectorService); - String data = oranVESEventAssembly.performAssembly(xPathFieldsMap, instant, NetconfConfigChange.class.getSimpleName(), - sequenceNo); - vesCollectorService.publishVESMessage(data); + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + if (mapper == null) { + this.mapper = new ORanNotifToVESEventAssembly(netconfAccessor, vesCollectorService); + } + VESCommonEventHeaderPOJO header = mapper.createVESCommonEventHeader(notificationProxyParser.getTime(notification), + NetconfConfigChange.class.getSimpleName(), sequenceNo); + VESNotificationFieldsPOJO body = + mapper.createVESNotificationFields(notificationProxyParser.parseNotificationProxy(notification), + NetconfConfigChange.class.getSimpleName()); + try { + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } catch (JsonProcessingException e) { + log.warn("Exception while generating JSON object ", e); + } + } } - } diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java index cae1bca52..6f5de9677 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultNotificationListener.java @@ -17,8 +17,21 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +import com.fasterxml.jackson.core.JsonProcessingException; +import java.time.Instant; +import java.time.format.DateTimeParseException; +import org.eclipse.jdt.annotation.Nullable; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.Alarm.FaultSeverity; import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.ORanFmListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,11 +42,69 @@ import org.slf4j.LoggerFactory; public class ORanFaultNotificationListener implements ORanFmListener { private static final Logger log = LoggerFactory.getLogger(ORanFaultNotificationListener.class); + private NetconfBindingAccessor netconfAccessor; + private DataProvider databaseService; + private VESCollectorService vesCollectorService; + private int counter = 0; + private ORanFaultToVESFaultMapper mapper = null; + + public ORanFaultNotificationListener(NetconfBindingAccessor netconfAccessor, DataProvider databaseService, + VESCollectorService vesCollectorService) { + this.netconfAccessor = netconfAccessor; + this.databaseService = databaseService; + this.vesCollectorService = vesCollectorService; + } @Override public void onAlarmNotif(AlarmNotif notification) { - log.info("onAlarmNotif {}", notification); + log.info("onAlarmNotif {}", notification.getClass().getSimpleName()); + @Nullable + DateAndTime eventTime = notification.getEventTime(); + try { + Instant eventTimeInstant = Instant.parse(eventTime.getValue()); + + FaultcurrentBuilder faultCurrent = new FaultcurrentBuilder(); + faultCurrent.setNodeId(netconfAccessor.getNodeId().getValue()); + faultCurrent.setObjectId(notification.getFaultSource()); + faultCurrent.setProblem(notification.getFaultText()); + faultCurrent.setSeverity(getSeverityType(notification.getFaultSeverity())); + faultCurrent.setCounter(Integer.valueOf(counter++)); + faultCurrent.setId(notification.getFaultId().toString()); + faultCurrent.setTimestamp(eventTime); + + databaseService.updateFaultCurrent(faultCurrent.build()); + + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + if (mapper == null) { + this.mapper = new ORanFaultToVESFaultMapper(netconfAccessor.getNodeId(), vesCollectorService, + AlarmNotif.class.getSimpleName()); + } + VESCommonEventHeaderPOJO header = + mapper.mapCommonEventHeader(notification, eventTimeInstant, counter); + VESFaultFieldsPOJO body = mapper.mapFaultFields(notification); + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } + } catch (JsonProcessingException | DateTimeParseException e) { + log.debug("Can not convert event into VES message {}", notification, e); + } + + } + + private SeverityType getSeverityType(FaultSeverity faultSeverity) { + String severity = faultSeverity.getName(); + switch (severity) { + case "CRITICAL": + return SeverityType.Critical; + case "MAJOR": + return SeverityType.Major; + case "MINOR": + return SeverityType.Minor; + case "WARNING": + return SeverityType.Warning; + default: + return SeverityType.NonAlarmed; + } } } diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultToVESFaultMapper.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultToVESFaultMapper.java new file mode 100644 index 000000000..1790f82c7 --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanFaultToVESFaultMapper.java @@ -0,0 +1,131 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; + +import java.time.Instant; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +//@formatter:off +/* + * Maps ORAN Fault fields to VES fault domain fields and VES commonEventHeader fields + * + * + * VES Fields Mapping + * domain "fault" + * eventId "nt:network-topology/nt:topology/nt:node/nt:node-id" + * eventName "nt:network-topology/nt:topology/nt:node/nt:node-id" + * eventType "O-RAN-RU-Fault" + * lastEpochMicrosec TimeStamp represented by <eventTime> field in NetConf notification header in unix time format - as microseconds elapsed since 1 Jan 1970 not including leap seconds. + * nfcNamingCode always "" + * nfNamingCode always "" + * nfVendorName ??? + * priority "Normal" + * reportingEntityId The OAM-Controller identifier with in the SMO - e.g. the fully qualified domain name or IP-Address. + * reportingEntityName as configured by helm charts for the OpenDaylight cluster name ?????? + * sequence As per NetConf notification increasing sequence number as unsigned integer 32 bits. The value is reused in the eventId field. + * sourceId ????? + * sourceName "nt:network-topology/nt:topology/nt:node/nt:node-id" + * startEpochMicrosec + * timeZoneOffset + * version "4.1" + * vesEventListenerVersion "7.2" + * + * + * alarmAdditionalInformation + * alarmCondition Value of "o-ran-fm:alarm-notif/fault-id" + * alarmInterfaceA Value of "o-ran-fm:alarm-notif/fault-source" + * eventCategory Static text "O-RU failure" + * eventSeverity Value of "o-ran-fm:alarm-notif/fault-severity". But if "o-ran-fm:alarm-notif/is-cleared" then "NORMAL" + * eventSourceType The value of ietf-hardware (RFC8348) /hardware/component[not(parent)][1]/mfg-model or "O-RU" if not found. + * faultFieldsVersion "4.0" + * specificProblem A mapping of the fault-id to its description according to O-RAN OpenFronthaul specification. + * vfStatus "Active" + * + */ +//@formatter:on + +public class ORanFaultToVESFaultMapper { + + private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); + private static final String VES_EVENT_DOMAIN = "fault"; + private static final String VES_EVENTTYPE = "ORAN_Fault"; + private static final String VES_EVENT_PRIORITY = "Normal"; + private static final String VES_EVENT_CATEGORY = "O-RU Failure"; + private static final String VES_FAULT_FIELDS_VERSION = "4.0"; + private static final String VES_FAULT_FIELDS_VFSTATUS = "Active"; //virtual function status + + private final VESCollectorService vesProvider; + private final String notifName; // Name + private final String nodeIdString; // Sourcename + + + public ORanFaultToVESFaultMapper(NodeId nodeId, VESCollectorService vesCollectorService, + String notifName) { + this.nodeIdString = nodeId.getValue(); + this.vesProvider = vesCollectorService; + this.notifName = notifName; + } + + public VESCommonEventHeaderPOJO mapCommonEventHeader(AlarmNotif notification, Instant eventTime, int sequenceNo) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventName(notifName); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + String eventId; + + eventId = notifName + "-" + Long.toUnsignedString(sequenceNo); + + vesCEH.setEventId(eventId); + vesCEH.setStartEpochMicrosec(eventTime.toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(eventTime.toEpochMilli() * 1000); + vesCEH.setNfVendorName("ORAN"); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo); + vesCEH.setSourceId("ORAN"); + vesCEH.setSourceName(nodeIdString); + + return vesCEH; + } + + public VESFaultFieldsPOJO mapFaultFields(AlarmNotif alarmNotif) { + VESFaultFieldsPOJO vesFaultFields = new VESFaultFieldsPOJO(); + + vesFaultFields.setAlarmCondition(alarmNotif.getFaultId().toString()); + vesFaultFields.setAlarmInterfaceA(alarmNotif.getFaultSource()); + vesFaultFields.setEventCategory(VES_EVENT_CATEGORY); + vesFaultFields.setEventSeverity(alarmNotif.getFaultSeverity().getName()); + vesFaultFields.setFaultFieldsVersion(VES_FAULT_FIELDS_VERSION); + vesFaultFields.setSpecificProblem(alarmNotif.getFaultText()); + vesFaultFields.setVfStatus(VES_FAULT_FIELDS_VFSTATUS); + + return vesFaultFields; + } + +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java index 757768573..df81f60bf 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNetworkElement.java @@ -17,6 +17,7 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +import com.fasterxml.jackson.core.JsonProcessingException; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -25,7 +26,10 @@ import org.onap.ccsdk.features.sdnr.wt.common.YangHelper; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElementService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNotifications; @@ -34,8 +38,12 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.r import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.Hardware; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.NetworkElementDeviceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev161109.NetconfCallhomeServer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev161109.netconf.callhome.server.AllowedDevices; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconf.callhome.server.rev161109.netconf.callhome.server.allowed.devices.Device; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -43,8 +51,6 @@ import org.opendaylight.yangtools.yang.binding.NotificationListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - */ public class ORanNetworkElement implements NetworkElement { private static final Logger log = LoggerFactory.getLogger(ORanNetworkElement.class); @@ -56,12 +62,14 @@ public class ORanNetworkElement implements NetworkElement { @SuppressWarnings("unused") private final VESCollectorService vesCollectorService; - private final ORanToInternalDataModel oRanMapper; - private ListenerRegistration<NotificationListener> oRanListenerRegistrationResult; private @NonNull final ORanChangeNotificationListener oRanListener; private ListenerRegistration<NotificationListener> oRanFaultListenerRegistrationResult; private @NonNull final ORanFaultNotificationListener oRanFaultListener; + private final NotificationProxyParser notificationProxyParser; + private @NonNull ORanRegistrationToVESpnfRegistrationMapper mapper; + private Collection<Component> componentList; + private static int sequenceNo = 0; ORanNetworkElement(NetconfBindingAccessor netconfAccess, DataProvider databaseService, VESCollectorService vesCollectorService) { @@ -69,98 +77,42 @@ public class ORanNetworkElement implements NetworkElement { this.netconfAccessor = netconfAccess; this.databaseService = databaseService; this.vesCollectorService = vesCollectorService; + this.notificationProxyParser = vesCollectorService.getNotificationProxyParser(); this.oRanListenerRegistrationResult = null; - this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, databaseService, vesCollectorService); + this.oRanListener = new ORanChangeNotificationListener(netconfAccessor, databaseService, vesCollectorService, + notificationProxyParser); this.oRanFaultListenerRegistrationResult = null; - this.oRanFaultListener = new ORanFaultNotificationListener(); - - this.oRanMapper = new ORanToInternalDataModel(); - + this.oRanFaultListener = + new ORanFaultNotificationListener(netconfAccessor, databaseService, vesCollectorService); } - public void initialReadFromNetworkElement() { - Hardware hardware = readHardware(netconfAccessor); + private void initialReadFromNetworkElement() { + Hardware hardware = readHardware(); if (hardware != null) { - Collection<Component> componentList = YangHelper.getCollection(hardware.getComponent()); - if (componentList != null) { - int componentListSize = componentList.size(); - int writeCount = 0; - - for (Component component : componentList) { - if (component.getParent() == null) { - writeCount += writeInventory(component, componentList, 0); - } - } - if (componentListSize != writeCount) { - log.warn("Not all data were written to the Inventory. Potential entries with missing " - + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}", - netconfAccessor.getNodeId().getValue(), componentListSize, writeCount); - } - } + componentList = YangHelper.getCollection(hardware.nonnullComponent()); + List<Inventory> inventoryList = + ORanToInternalDataModel.getInventoryList(netconfAccessor.getNodeId(), componentList); + inventoryList.forEach(databaseService::writeInventory); } - System1 sys = getOnapSystemData(netconfAccessor); - if (sys != null) { - GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder(); - gcBuilder.setId(sys.getName()).setName(sys.getName()).setWeburi(sys.getWebUi().getValue()); - databaseService.writeGuiCutThroughData(gcBuilder.build()); + Optional<Guicutthrough> oGuicutthrough = ORanToInternalDataModel.getGuicutthrough(getOnapSystemData()); + if (oGuicutthrough.isPresent()) { + databaseService.writeGuiCutThroughData(oGuicutthrough.get(), netconfAccessor.getNodeId().getValue()); } } - private int writeInventory(Component component, Collection<Component> componentList, int treeLevel) { - databaseService - .writeInventory(oRanMapper.getInternalEquipment(netconfAccessor.getNodeId(), component, treeLevel)); - int count = 1; - if (component.getContainsChild() != null) { - List<String> containerHolderList = component.getContainsChild(); - for (String containerHolder : containerHolderList) { - for (Component c : componentList) { - if (containerHolder.equals(c.getName())) { - count += writeInventory(c, componentList, treeLevel + 1); - } - } - } - } - return count; - } - @Override public NetworkElementDeviceType getDeviceType() { return NetworkElementDeviceType.ORAN; } - private System1 getOnapSystemData(NetconfBindingAccessor accessData) { - InstanceIdentifier<System1> system1IID = InstanceIdentifier - .builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.system.rev140806.System.class) - .augmentation(System1.class).build(); - - System1 res = accessData.getTransactionUtils().readData(accessData.getDataBroker(), - LogicalDatastoreType.OPERATIONAL, system1IID); - log.debug("Result of getOnapSystemData = {}", res); - return res; - } - - private Hardware readHardware(NetconfBindingAccessor accessData) { - - final Class<Hardware> clazzPac = Hardware.class; - - log.info("DBRead Get equipment for class {} from mountpoint {} for uuid {}", clazzPac.getSimpleName(), - accessData.getNodeId().getValue()); - - InstanceIdentifier<Hardware> hardwareIID = InstanceIdentifier.builder(clazzPac).build(); - - Hardware res = accessData.getTransactionUtils().readData(accessData.getDataBroker(), - LogicalDatastoreType.OPERATIONAL, hardwareIID); - - return res; - } - @Override public void register() { - initialReadFromNetworkElement(); + // Publish the mountpoint to VES if enabled + publishMountpointToVES(); // Register call back class for receiving notifications Optional<NetconfNotifications> oNotifications = netconfAccessor.getNotificationAccessor(); if (oNotifications.isPresent()) { @@ -208,4 +160,83 @@ public class ORanNetworkElement implements NetworkElement { return Optional.of(netconfAccessor); } + // Read from device + private System1 getOnapSystemData() { + log.info("Get System1 for class {} from mountpoint {}", netconfAccessor.getNodeId().getValue()); + + InstanceIdentifier<System1> system1IID = InstanceIdentifier + .builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.system.rev140806.System.class) + .augmentation(System1.class).build(); + System1 res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(), + LogicalDatastoreType.OPERATIONAL, system1IID); + log.debug("Result of System1 = {}", res); + return res; + } + + private Hardware readHardware() { + final Class<Hardware> clazzPac = Hardware.class; + log.info("DBRead Get hardware for class {} from mountpoint {}", clazzPac.getSimpleName(), + netconfAccessor.getNodeId().getValue()); + InstanceIdentifier<Hardware> hardwareIID = InstanceIdentifier.builder(clazzPac).build(); + Hardware res = netconfAccessor.getTransactionUtils().readData(netconfAccessor.getDataBroker(), + LogicalDatastoreType.OPERATIONAL, hardwareIID); + log.debug("Result of Hardware = {}", res); + return res; + } + + private void publishMountpointToVES() { + log.debug("In publishMountpointToVES()"); + + /** + * 1. Check if this device is in the list of allowed-devices. + * 2. If device exists in allowed-devices, then create VES pnfRegistration event and publish to VES + */ + if (inAllowedDevices(netconfAccessor.getNodeId().getValue())) { + if (vesCollectorService.getConfig().isVESCollectorEnabled()) { + + for (Component component : ORanToInternalDataModel.getRootComponents(componentList)) { + //Just get one component. At the moment we don't care which one. Also since there is only one management address, we assume there will be only one chassis. + //If the device supports subtended configuration then it is assumed that the Chassis containing the management interface will be the root component and there will be only one root. + this.mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, + vesCollectorService, component); + VESCommonEventHeaderPOJO header = + mapper.mapCommonEventHeader(sequenceNo++); + VESPNFRegistrationFieldsPOJO body = mapper.mapPNFRegistrationFields(); + try { + vesCollectorService.publishVESMessage(vesCollectorService.generateVESEvent(header, body)); + } catch (JsonProcessingException e) { + log.warn("Error while serializing VES Event to String ", e); + e.printStackTrace(); + } + + } + } + + } + + } + + private boolean inAllowedDevices(String mountpointName) { + final InstanceIdentifier<AllowedDevices> ALL_DEVICES = + InstanceIdentifier.create(NetconfCallhomeServer.class).child(AllowedDevices.class); + + AllowedDevices allowedDevices; + allowedDevices = netconfAccessor.getTransactionUtils().readData( + netconfAccessor.getControllerBindingDataBroker(), LogicalDatastoreType.CONFIGURATION, ALL_DEVICES); + + if (allowedDevices != null) { + Collection<Device> deviceList = YangHelper.getCollection(allowedDevices.nonnullDevice()); + for (Device device : deviceList) { + log.info("Device in allowed-devices is - {}", device.getUniqueId()); + if (device.getUniqueId().equals(netconfAccessor.getNodeId().getValue())) { + log.info("Mountpoint is part of allowed-devices list"); + return true; + } + } + } + + log.info("Mountpoint {} is not part of allowed-devices list", mountpointName); + return false; + } + } diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java index b7506e50c..d99f1c874 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotifToVESEventAssembly.java @@ -21,19 +21,15 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.VESCommonEventHeaderPOJO; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.VESEvent; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; -import org.opendaylight.yangtools.yang.binding.DataObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,38 +47,8 @@ public class ORanNotifToVESEventAssembly { this.vesProvider = vesProvider; } - public String performAssembly(HashMap<String, String> xPathFieldsMap, Instant instant, String notificationTypeName, - long sequenceNo) { - VESEvent data = assembleVESEventMsg(xPathFieldsMap, instant, notificationTypeName, sequenceNo); - return createVESEventJSON(data); - } - - public VESEvent assembleVESEventMsg(HashMap<String, String> xPathFieldsMap, Instant instant, - String notificationTypeName, long sequenceNo) { - VESCommonEventHeaderPOJO vesCEH = createVESCommonEventHeader(instant, notificationTypeName, sequenceNo); - VESNotificationFieldsPOJO vesNotifFields = createVESNotificationFields(xPathFieldsMap, notificationTypeName); - - VESEvent vesEvent = new VESEvent(); - vesEvent.addEventObjects(vesCEH); - vesEvent.addEventObjects(vesNotifFields); - - return vesEvent; - } - - public String createVESEventJSON(VESEvent vesEvent) { - String oranVESMsg = ""; - try { - ObjectMapper objMapper = new ObjectMapper(); - oranVESMsg = objMapper.writeValueAsString(vesEvent); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - log.debug("VES Message generated from ORAN Netconf Notification is - {}", oranVESMsg); - return oranVESMsg; - } - // VES CommonEventHeader fields - private VESCommonEventHeaderPOJO createVESCommonEventHeader(Instant time, String notificationTypeName, + public VESCommonEventHeaderPOJO createVESCommonEventHeader(Instant time, String notificationTypeName, long sequenceNo) { VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); vesCEH.setDomain(VES_EVENT_DOMAIN); @@ -95,8 +61,8 @@ public class ORanNotifToVESEventAssembly { eventId = notificationTypeName + "-" + Long.toUnsignedString(sequenceNo); vesCEH.setEventId(eventId); - vesCEH.setStartEpochMicrosec(time.toEpochMilli() * 100); - vesCEH.setLastEpochMicrosec(time.toEpochMilli() * 100); + vesCEH.setStartEpochMicrosec(time.toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(time.toEpochMilli() * 1000); vesCEH.setNfVendorName("ORAN"); vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); vesCEH.setSequence(sequenceNo); @@ -106,7 +72,7 @@ public class ORanNotifToVESEventAssembly { } // Notification fields - private VESNotificationFieldsPOJO createVESNotificationFields(HashMap<String, String> xPathFields, + public VESNotificationFieldsPOJO createVESNotificationFields(HashMap<String, String> xPathFields, String notificationTypeName) { VESNotificationFieldsPOJO vesNotifFields = new VESNotificationFieldsPOJO(); diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java new file mode 100644 index 000000000..81605e450 --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanRegistrationToVESpnfRegistrationMapper.java @@ -0,0 +1,87 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; + +import java.time.Instant; +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ORanRegistrationToVESpnfRegistrationMapper { + + private static final Logger LOG = LoggerFactory.getLogger(ORanFaultToVESFaultMapper.class); + //CommonEventHeader fields + private static final String VES_EVENT_DOMAIN = "pnfRegistration"; + private static final String VES_EVENTTYPE = "NetConf Callhome Registration"; + private static final String VES_EVENT_PRIORITY = "Normal"; + + private final VESCollectorService vesProvider; + private final @NonNull Component component; + private final NetconfAccessor netconfAccessor; + + public ORanRegistrationToVESpnfRegistrationMapper(NetconfAccessor netconfAccessor, + VESCollectorService vesCollectorService, Component component) { + this.netconfAccessor = netconfAccessor; + this.vesProvider = vesCollectorService; + this.component = component; + } + + public VESCommonEventHeaderPOJO mapCommonEventHeader(int sequenceNo) { + VESCommonEventHeaderPOJO vesCEH = new VESCommonEventHeaderPOJO(); + vesCEH.setDomain(VES_EVENT_DOMAIN); + vesCEH.setEventId(netconfAccessor.getNodeId().getValue()); + vesCEH.setEventName(netconfAccessor.getNodeId().getValue()); + vesCEH.setEventType(VES_EVENTTYPE); + vesCEH.setPriority(VES_EVENT_PRIORITY); + + vesCEH.setStartEpochMicrosec(Instant.now().toEpochMilli() * 1000); + vesCEH.setLastEpochMicrosec(Instant.now().toEpochMilli() * 1000); + vesCEH.setNfVendorName(component.getMfgName()); + vesCEH.setReportingEntityName(vesProvider.getConfig().getReportingEntityName()); + vesCEH.setSequence(sequenceNo); + vesCEH.setSourceId(component.getUuid().toString()); + vesCEH.setSourceName(netconfAccessor.getNodeId().getValue()); + + return vesCEH; + } + + public VESPNFRegistrationFieldsPOJO mapPNFRegistrationFields() { + VESPNFRegistrationFieldsPOJO vesPnfFields = new VESPNFRegistrationFieldsPOJO(); + vesPnfFields.setModelNumber(component.getModelName()); + vesPnfFields.setOamV4IpAddress(netconfAccessor.getNetconfNode().getHost().getIpAddress().toString()); + //vesPnfFields.setOamV6IpAddress(oamV6IpAddress); // Check if IP address in V6 format and then include it. Same with v4 address also + vesPnfFields.setSerialNumber(component.getSerialNum()); + vesPnfFields.setVendorName(component.getMfgName()); + vesPnfFields.setSoftwareVersion(component.getSoftwareRev()); + vesPnfFields.setUnitType(component.getAlias()); + vesPnfFields.setUnitFamily(component.getXmlClass().toString()); + vesPnfFields.setManufactureDate(component.getMfgDate().toString()); + //vesPnfFields.setLastServiceDate(component.getLastChange()); + + return vesPnfFields; + } +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java index ca44e63f2..1f84db41c 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java +++ b/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanToInternalDataModel.java @@ -18,59 +18,186 @@ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.onap.system.rev201026.System1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Guicutthrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.GuicutthroughBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.Inventory; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.InventoryBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.binding.CodeHelpers; import org.opendaylight.yangtools.yang.common.Uint32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * @author herbert + * Convert data to data-provider model and perform consistency checks.<br> + * <b>Component list characteristics:</b><br> + * <ul> + * <li>component list is a flat list tree structure specified + * <li>via "component.getParent()": + * <ul> + * <li>If null we have a root element + * <li>if not null it is a child element with generated child level<br> + * </ul> + * </ul> + * Example of List:<br> + * * */ public class ORanToInternalDataModel { - public Inventory getInternalEquipment(NodeId nodeId, Component component, int treeLevel) { + private static final Logger log = LoggerFactory.getLogger(ORanToInternalDataModel.class); + + public static List<Inventory> getInventoryList(NodeId nodeId, Collection<Component> componentList) { - InventoryBuilder inventoryBuilder = new InventoryBuilder(); + List<Inventory> inventoryResultList = new ArrayList<Inventory>(); + for (Component component : getRootComponents(componentList)) { + inventoryResultList = recurseGetInventory(nodeId, component, componentList, 0, inventoryResultList); + } + // Verify if result is complete + if (componentList.size() != inventoryResultList.size()) { + log.warn( + "Not all data were written to the Inventory. Potential entries with missing " + + "contained-child. Node Id = {}, Components Found = {}, Entries written to Database = {}", + nodeId.getValue(), componentList.size(), inventoryResultList.size()); + } + return inventoryResultList; + } - // General - inventoryBuilder.setNodeId(nodeId.getValue()); - inventoryBuilder.setParentUuid(component.getParent()!=null?component.getParent():component.getName()); - inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel)); + private static List<Inventory> recurseGetInventory(NodeId nodeId, Component component, + Collection<Component> componentList, int treeLevel, List<Inventory> inventoryResultList) { - inventoryBuilder.setUuid(component.getName()); - // -- String list with ids of holders - List<String> containerHolderKeyList = new ArrayList<>(); - List<String> containerHolderList = component.getContainsChild(); - if (containerHolderList != null) { - for (String containerHolder : containerHolderList) { - containerHolderKeyList.add(containerHolder); + //Add element to list, if conversion successfull + Optional<Inventory> oInventory = getInternalEquipment(nodeId, component, treeLevel); + if (oInventory.isPresent()) { + inventoryResultList.add(oInventory.get()); + } + //Walk trough list of child keys and add to list + for (String childUuid : CodeHelpers.nonnull(component.getContainsChild())) { + for (Component c : getComponentsByName(childUuid, componentList)) { + inventoryResultList = recurseGetInventory(nodeId, c, componentList, treeLevel + 1, inventoryResultList); } } - inventoryBuilder.setContainedHolder(containerHolderKeyList); - // -- Manufacturer related things - inventoryBuilder.setManufacturerName(component.getMfgName()); - inventoryBuilder.setManufacturerIdentifier(component.getMfgName()); + return inventoryResultList; + } + public static List<Component> getRootComponents(Collection<Component> componentList) { + List<Component> resultList = new ArrayList<>(); + for (Component c : componentList) { + if (c.getParent() == null) { // Root elements do not have a parent + resultList.add(c); + } + } + return resultList; + } - // Equipment type - inventoryBuilder.setDescription(component.getDescription()); - inventoryBuilder.setModelIdentifier(component.getModelName()); - if (component.getXmlClass() != null) { - inventoryBuilder.setPartTypeId(component.getXmlClass().getName()); + private static List<Component> getComponentsByName(String name, Collection<Component> componentList) { + List<Component> resultList = new ArrayList<>(); + for (Component c : componentList) { + if (name.equals(c.getName())) { // <-- Component list is flat search for child's of name + resultList.add(c); + } } - inventoryBuilder.setTypeName(component.getName()); - inventoryBuilder.setVersion(component.getHardwareRev()); + return resultList; + } + + /** + * Convert equipment into Inventory. Decide if inventory can by created from content or not. + * Public for test case. + * @param nodeId of node (Similar to mountpointId) + * @param component to handle + * @param treeLevel of components + * @return Inventory if possible to be created. + */ + public static Optional<Inventory> getInternalEquipment(NodeId nodeId, Component component, int treeLevel) { + + // Make sure that expected data are not null + Objects.requireNonNull(nodeId); + Objects.requireNonNull(component); + + // Read manadatory data + @Nullable + String nodeIdString = nodeId.getValue(); + @Nullable + String uuid = component.getName(); + @Nullable + String idParent = component.getParent(); + @Nullable + String uuidParent = idParent != null ? idParent : uuid; //<- Passt nicht - // Equipment instance - if (component.getMfgDate() != null) { - inventoryBuilder.setDate(component.getMfgDate().getValue()); + // do consistency check if all mandatory parameters are there + if (treeLevel >= 0 && nodeIdString != null && uuid != null && uuidParent != null) { + + // Build output data + + InventoryBuilder inventoryBuilder = new InventoryBuilder(); + + // General assumed as mandatory + inventoryBuilder.setNodeId(nodeIdString); + inventoryBuilder.setUuid(uuid); + inventoryBuilder.setParentUuid(uuidParent); + inventoryBuilder.setTreeLevel(Uint32.valueOf(treeLevel)); + + // -- String list with ids of holders (optional) + inventoryBuilder.setContainedHolder(CodeHelpers.nonnull(component.getContainsChild())); + + // -- Manufacturer related things (optional) + @Nullable + String mfgName = component.getMfgName(); + inventoryBuilder.setManufacturerName(mfgName); + inventoryBuilder.setManufacturerIdentifier(mfgName); + + // Equipment type (optional) + inventoryBuilder.setDescription(component.getDescription()); + inventoryBuilder.setModelIdentifier(component.getModelName()); + @Nullable + Class<? extends HardwareClass> xmlClass = component.getXmlClass(); + if (xmlClass != null) { + inventoryBuilder.setPartTypeId(xmlClass.getName()); + } + inventoryBuilder.setTypeName(component.getName()); + inventoryBuilder.setVersion(component.getHardwareRev()); + + // Equipment instance (optional) + @Nullable + DateAndTime mfgDate = component.getMfgDate(); + if (mfgDate != null) { + inventoryBuilder.setDate(mfgDate.getValue()); + } + inventoryBuilder.setSerial(component.getSerialNum()); + + return Optional.of(inventoryBuilder.build()); + } + return Optional.empty(); + } + + public static Optional<Guicutthrough> getGuicutthrough(@Nullable System1 sys) { + if (sys != null) { + String name = sys.getName(); + @Nullable + Uri uri = sys.getWebUi(); + if (uri != null) { + GuicutthroughBuilder gcBuilder = new GuicutthroughBuilder(); + if (name != null) { + gcBuilder.setName(name); + } + gcBuilder.setWeburi(uri.getValue()); + return Optional.of(gcBuilder.build()); + } + log.warn("Uri not set to invoke a Gui cut through session to the device. Please set the Uri in the device"); } - inventoryBuilder.setSerial(component.getSerialNum()); - return inventoryBuilder.build(); + log.warn("Retrieving augmented System details failed. Gui cut through information not available"); + return Optional.empty(); } } diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/ComponentHelper.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/ComponentHelper.java new file mode 100644 index 000000000..7b8380442 --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/ComponentHelper.java @@ -0,0 +1,179 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.json.JSONArray; +import org.json.JSONObject; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Fan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Port; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.Sensor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.AdminState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.OperState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorStatus; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorValue; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.SensorValueType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.ComponentBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.SensorData; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.SensorDataBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.State; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.component.StateBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; + +public class ComponentHelper { + + public static Component get(String name, String dateTimeString) { + DateAndTime dateTime = new DateAndTime(dateTimeString); + Uuid uuid = new Uuid("0Aabcdef-0abc-0cfD-0abC-0123456789AB"); + + ComponentBuilder componentBuilder = new ComponentBuilder(); + componentBuilder.setParent("Shelf").setName("Slot-0").setParentRelPos(0); + componentBuilder.setUuid(uuid); + componentBuilder.setContainsChild(Arrays.asList("Card-01A", "Card-01B")); + componentBuilder.setDescription("ORAN Network Element NO-456"); + componentBuilder.setXmlClass(TestHardwareClass.class); + componentBuilder.setMfgName("Nokia"); + componentBuilder.setMfgDate(dateTime); + return componentBuilder.build(); + } + + public static List<Component> getComponentList(String resourceName) { + try (Scanner scanner = new Scanner(ComponentHelper.class.getResourceAsStream(resourceName), "UTF-8")) { + String jsonString = scanner.useDelimiter("\\A").next(); + JSONObject jsonHardware = new JSONObject(jsonString).getJSONObject("hardware"); + JSONArray jsonComponentArray = jsonHardware.getJSONArray("component"); + return IntStream.range(0, jsonComponentArray.length()) + .mapToObj(idx -> ComponentHelper.get(jsonComponentArray.getJSONObject(idx))) + .collect(Collectors.toList()); + } + } + + public static Component get(JSONObject jsonComponent) { + ComponentBuilder componentBuilder = new ComponentBuilder(); + componentBuilder.setName(getString(jsonComponent, "name")); + componentBuilder.setParent(getString(jsonComponent, "parent")); + componentBuilder.setParentRelPos(getInteger(jsonComponent, "parent-rel-pos")); + componentBuilder.setAlias(getString(jsonComponent, "alias")); + componentBuilder.setXmlClass(getXmlClass(jsonComponent, "class")); + componentBuilder.setState(getState(jsonComponent, "state")); + componentBuilder.setDescription(getString(jsonComponent, "description")); + componentBuilder.setContainsChild(getStringArray(jsonComponent, "contains-child")); + componentBuilder.setSensorData(getSensorData(jsonComponent, "sensor-data")); + componentBuilder.setFirmwareRev(getString(jsonComponent, "firmware-rev")); + componentBuilder.setSerialNum(getString(jsonComponent, "serial-num")); + componentBuilder.setSoftwareRev(getString(jsonComponent, "software-rev")); + return componentBuilder.build(); + } + + // Private + + private static State getState(JSONObject jsonComponent, String key) { + if (jsonComponent.has(key)) { + JSONObject jsonState = jsonComponent.getJSONObject(key); + StateBuilder stateBuilder = new StateBuilder(); + stateBuilder.setOperState(getString(jsonState, "oper-state", value -> OperState.forName(value)).get()); + stateBuilder.setAdminState(getString(jsonState, "admin-state", value -> AdminState.forName(value)).get()); + return stateBuilder.build(); + } + return null; + } + + private static SensorData getSensorData(JSONObject jsonComponent, String key) { + if (jsonComponent.has(key)) { + JSONObject jsonSonsor = jsonComponent.getJSONObject(key); + SensorDataBuilder sensorBuilder = new SensorDataBuilder(); + sensorBuilder.setValueTimestamp(getString(jsonSonsor, "value-timestamp", value -> new DateAndTime(value))); + sensorBuilder.setValue(getInteger(jsonSonsor, "value", value -> new SensorValue(value))); + sensorBuilder + .setValueType(getString(jsonSonsor, "value-type", value -> SensorValueType.forName(value).get())); + sensorBuilder + .setOperStatus(getString(jsonSonsor, "oper-status", value -> SensorStatus.forName(value).get())); + return sensorBuilder.build(); + } + return null; + } + + // Get data types + private static Class<? extends HardwareClass> getXmlClass(JSONObject jsonComponent, String key) { + return getString(jsonComponent, key, value -> { + switch (value) { + case "iana-hardware:sensor": + return Sensor.class; + case "iana-hardware:port": + return Port.class; + case "iana-hardware:fan": + return Fan.class; + default: + return HardwareClass.class; + } + }); + } + + private static String getString(JSONObject jsonObject, String key) { + return getString(jsonObject, key, value -> value); + } + + private static Integer getInteger(JSONObject jsonObject, String key) { + return getInteger(jsonObject, key, value -> value); + } + + private interface ConvertString<T> { + T convert(String value); + } + + private static <T> T getString(JSONObject jsonObject, String key, ConvertString<T> convert) { + if (jsonObject.has(key)) { + String value = jsonObject.getString(key); + return convert.convert(value); + } + return null; + } + + private interface ConvertInteger<T> { + T convert(int value); + } + + private static <T> T getInteger(JSONObject jsonObject, String key, ConvertInteger<T> convert) { + if (jsonObject.has(key)) { + int value = jsonObject.getInt(key); + return convert.convert(value); + } + return null; + } + + private static List<String> getStringArray(JSONObject jsonComponent, String key) { + if (jsonComponent.has(key)) { + JSONArray stringArray = jsonComponent.getJSONArray(key); + return IntStream.range(0, stringArray.length()).mapToObj(idx -> stringArray.getString(idx)) + .collect(Collectors.toList()); + } + return null; + } + +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestAlarmNotif.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestAlarmNotif.java new file mode 100644 index 000000000..365b3a226 --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestAlarmNotif.java @@ -0,0 +1,77 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test; + +import java.util.Map; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.AlarmNotif; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.alarm.AffectedObjects; +import org.opendaylight.yang.gen.v1.urn.o.ran.fm._1._0.rev190204.alarm.AffectedObjectsKey; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.common.Uint16; + +public class TestAlarmNotif implements AlarmNotif { + + private static final Uint16 FAULT_ID = Uint16.valueOf(123); + + @Override + public <A extends Augmentation<AlarmNotif>> @Nullable A augmentation(Class<A> augmentationType) { + return null; + } + + @Override + public @Nullable Uint16 getFaultId() { + return FAULT_ID; + } + + @Override + public @Nullable String getFaultSource() { + return "ORAN-RU-FH"; + } + + @Override + public @Nullable Map<AffectedObjectsKey, AffectedObjects> getAffectedObjects() { + return null; + } + + @Override + public @Nullable FaultSeverity getFaultSeverity() { + return FaultSeverity.CRITICAL; + } + + @Override + public @Nullable Boolean isIsCleared() { + return true; + } + + @Override + public @Nullable String getFaultText() { + return "CPRI Port Down"; + } + + @Override + public @Nullable DateAndTime getEventTime() { + return new DateAndTime("2021-03-23T18:19:42.326144Z"); + } + +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestDeviceManagerORanImpl.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestDeviceManagerORanImpl.java index 6abe07285..7b05342c4 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestDeviceManagerORanImpl.java +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestDeviceManagerORanImpl.java @@ -19,9 +19,7 @@ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test; import static org.mockito.Mockito.mock; import java.io.IOException; -import org.junit.After; import org.junit.Before; -import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.DeviceManagerORanImpl; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; @@ -32,7 +30,7 @@ public class TestDeviceManagerORanImpl { public void init() throws InterruptedException, IOException { } - @Test + // @Test public void test() throws Exception { devMgrOran = new DeviceManagerORanImpl(); NetconfNetworkElementService netconfNetworkElementService = mock(NetconfNetworkElementService.class); @@ -45,7 +43,7 @@ public class TestDeviceManagerORanImpl { } } - @After + //@After public void cleanUp() throws Exception { devMgrOran.close(); } diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanChangeNotificationListener.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanChangeNotificationListener.java index 052b5a711..dd5fa7fae 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanChangeNotificationListener.java +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanChangeNotificationListener.java @@ -18,15 +18,19 @@ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test; -import static org.mockito.Mockito.*; - +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.time.Instant; import java.util.Arrays; import java.util.List; - import org.eclipse.jdt.annotation.NonNull; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanChangeNotificationListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; @@ -41,23 +45,34 @@ import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; +@RunWith(MockitoJUnitRunner.class) public class TestORanChangeNotificationListener { private static final String NODEID = "node1"; + @Mock + NetconfBindingAccessor netconfAccessor; + @Mock + DataProvider databaseService; + @Mock + VESCollectorService vesCollectorService; + @Mock + VESCollectorCfgService vesCfgService; + @Mock + NotificationProxyParser notifProxyParser; + @Mock + static NetconfConfigChange change; + @Test public void test() { - NetconfBindingAccessor netconfAccessor = mock(NetconfBindingAccessor.class); - DataProvider databaseService = mock(DataProvider.class); - VESCollectorService vesCollectorService = mock(VESCollectorService.class); - VESCollectorCfgService vesCfgService = mock(VESCollectorCfgService.class); - when(vesCollectorService.getConfig()).thenReturn(vesCfgService); - when(vesCfgService.getReportingEntityName()).thenReturn("SDN-R"); - ORanChangeNotificationListener notifListener = - new ORanChangeNotificationListener(netconfAccessor, databaseService, vesCollectorService); when(netconfAccessor.getNodeId()).thenReturn(new NodeId(NODEID)); + when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); + + ORanChangeNotificationListener notifListener = + new ORanChangeNotificationListener(netconfAccessor, databaseService, vesCollectorService, notifProxyParser); + Iterable<? extends PathArgument> pathArguments = Arrays.asList(new PathArgument() { @Override @@ -71,8 +86,9 @@ public class TestORanChangeNotificationListener { } }); InstanceIdentifier<?> target = InstanceIdentifier.create(pathArguments); - - notifListener.onNetconfConfigChange(createNotification(EditOperationType.Create, target)); + NetconfConfigChange confChangeNotification = createNotification(EditOperationType.Create, target); + when(notifProxyParser.getTime(confChangeNotification)).thenReturn(Instant.now()); + notifListener.onNetconfConfigChange(confChangeNotification); EventlogEntity event = new EventlogBuilder().setNodeId(NODEID) .setNewValue(String.valueOf(EditOperationType.Create)).setObjectId(target.toString()).build(); verify(databaseService).writeEventLog(event); @@ -84,8 +100,6 @@ public class TestORanChangeNotificationListener { * @return */ private static NetconfConfigChange createNotification(EditOperationType type, InstanceIdentifier<?> target) { - NetconfConfigChange change = mock(NetconfConfigChange.class); - @SuppressWarnings("null") final @NonNull List<Edit> edits = Arrays.asList(new EditBuilder().setOperation(type).setTarget(target).build()); when(change.nonnullEdit()).thenReturn(edits); diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanFaultNotificationListener.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanFaultNotificationListener.java index d486f6735..b536460a0 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanFaultNotificationListener.java +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanFaultNotificationListener.java @@ -17,14 +17,49 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanFaultNotificationListener; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.FaultcurrentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.data.provider.rev201110.SeverityType; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +@RunWith(MockitoJUnitRunner.class) public class TestORanFaultNotificationListener { + @Mock + NetconfBindingAccessor bindingAccessor; + @Mock + DataProvider dataProvider; + @Mock + VESCollectorService vesCollectorService; + @Mock + VESCollectorCfgService vesCfgService; + @Test public void test() { - ORanFaultNotificationListener faultListener = new ORanFaultNotificationListener(); - faultListener.onAlarmNotif(null); + when(bindingAccessor.getNodeId()).thenReturn(new NodeId("nSky")); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); + + ORanFaultNotificationListener faultListener = new ORanFaultNotificationListener(bindingAccessor, dataProvider, vesCollectorService); + faultListener.onAlarmNotif(new TestAlarmNotif()); + verify(dataProvider).updateFaultCurrent(new FaultcurrentBuilder().setCounter(0) + .setNodeId("nSky") + .setId("123") + .setProblem("CPRI Port Down") + .setSeverity(SeverityType.Critical) + .setObjectId("ORAN-RU-FH") + .setTimestamp(new DateAndTime("2021-03-23T18:19:42.326144Z")) + .build()); } } diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElement.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElement.java index a0321206c..2ca59d916 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElement.java +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElement.java @@ -23,60 +23,76 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.Optional; -import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.DataProvider; import org.onap.ccsdk.features.sdnr.wt.devicemanager.ne.service.NetworkElement; import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanNetworkElementFactory; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test.mock.TransactionUtilsMock; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; import org.opendaylight.yang.gen.v1.urn.o.ran.hardware._1._0.rev190328.ORANHWCOMPONENT; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.QName; public class TestORanNetworkElement { + private static final QName OneCell = + QName.create("urn:onf:otcc:wireless:yang:radio-access:commscope-onecell", "2020-06-22", "onecell").intern(); private static String NODEIDSTRING = "nSky"; + private static NodeId nodeId = new NodeId(NODEIDSTRING); + private static NodeId nNodeId = new NodeId("nSky"); - private static NetconfBindingAccessor accessor; + private static NetconfAccessor accessor; private static DeviceManagerServiceProvider serviceProvider; private static Capabilities capabilities; + private static TransactionUtils transactionUtils; + private static NetconfBindingAccessor bindingCommunicator; + private static VESCollectorService vesCollectorService; + private static NotificationProxyParser notificationProxyParser; + private static VESCollectorCfgService vesCfgService; @BeforeClass public static void init() throws InterruptedException, IOException { capabilities = mock(Capabilities.class); - accessor = mock(NetconfBindingAccessor.class); + accessor = mock(NetconfAccessor.class); serviceProvider = mock(DeviceManagerServiceProvider.class); + transactionUtils = mock(TransactionUtils.class); + bindingCommunicator = mock(NetconfBindingAccessor.class); + vesCollectorService = mock(VESCollectorService.class); + notificationProxyParser = mock(NotificationProxyParser.class); + vesCfgService = mock(VESCollectorCfgService.class); - NetconfBindingAccessor bindingCommunicator = mock(NetconfBindingAccessor.class); - NodeId nodeId = new NodeId(NODEIDSTRING); - when(bindingCommunicator.getTransactionUtils()).thenReturn(mock(TransactionUtils.class)); - when(bindingCommunicator.getNodeId()).thenReturn(nodeId); - - NodeId nNodeId = new NodeId("nSky"); when(accessor.getCapabilites()).thenReturn(capabilities); when(accessor.getNodeId()).thenReturn(nNodeId); - when(accessor.getTransactionUtils()).thenReturn(new TransactionUtilsMock()); + when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingCommunicator)); + when(bindingCommunicator.getTransactionUtils()).thenReturn(transactionUtils); + when(bindingCommunicator.getNodeId()).thenReturn(nodeId); + when(vesCollectorService.getNotificationProxyParser()).thenReturn(notificationProxyParser); DataProvider dataProvider = mock(DataProvider.class); when(serviceProvider.getDataProvider()).thenReturn(dataProvider); - when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingCommunicator)); - + when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.isVESCollectorEnabled()).thenReturn(true); } @Test public void test() { - NetconfBindingAccessor bindingCommunicator = mock(NetconfBindingAccessor.class); + NodeId nodeId = new NodeId(NODEIDSTRING); when(bindingCommunicator.getTransactionUtils()).thenReturn(mock(TransactionUtils.class)); when(bindingCommunicator.getNodeId()).thenReturn(nodeId); Optional<NetworkElement> oRanNe; - when(accessor.getCapabilites().isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(true); + when(capabilities.isSupportingNamespace(ORANHWCOMPONENT.QNAME)).thenReturn(true); + when(capabilities.isSupportingNamespace(OneCell)).thenReturn(false); ORanNetworkElementFactory factory = new ORanNetworkElementFactory(); oRanNe = factory.create(accessor, serviceProvider); assertTrue(factory.create(accessor, serviceProvider).isPresent()); @@ -87,8 +103,4 @@ public class TestORanNetworkElement { assertEquals(oRanNe.get().getNodeId().getValue(), "nSky"); } - @After - public void cleanUp() throws Exception { - - } -} + } diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java index f6ca70ad1..0da5ec1f4 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanNetworkElementFactory.java @@ -27,6 +27,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanNetworkElementFactory; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServiceProvider; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; @@ -40,6 +41,7 @@ public class TestORanNetworkElementFactory { private static NetconfBindingAccessor accessor; private static DeviceManagerServiceProvider serviceProvider; private static Capabilities capabilities; + private static VESCollectorService vesCollectorService; @BeforeClass public static void init() throws InterruptedException, IOException { @@ -51,12 +53,12 @@ public class TestORanNetworkElementFactory { capabilities = mock(Capabilities.class); accessor = mock(NetconfBindingAccessor.class); serviceProvider = mock(DeviceManagerServiceProvider.class); + vesCollectorService = mock(VESCollectorService.class); when(accessor.getCapabilites()).thenReturn(capabilities); when(accessor.getNetconfBindingAccessor()).thenReturn(Optional.of(bindingCommunicator)); when(serviceProvider.getDataProvider()).thenReturn(null); - - + when(serviceProvider.getVESCollectorService()).thenReturn(vesCollectorService); } @Test diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanRegistrationToVESpnfRegistration.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanRegistrationToVESpnfRegistration.java new file mode 100644 index 000000000..781d333fe --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanRegistrationToVESpnfRegistration.java @@ -0,0 +1,248 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test; + +import static org.mockito.Mockito.when; +import java.math.BigDecimal; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanRegistrationToVESpnfRegistrationMapper; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.augmented.optional.fields.IgnoreMissingSchemaSources; +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.netconf.node.connection.parameters.NonModuleCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.OdlHelloMessageCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.YangModuleCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.PassThrough; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.UnavailableCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.schema.storage.YangLibrary; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint32; + +@RunWith(MockitoJUnitRunner.class) +public class TestORanRegistrationToVESpnfRegistration { + + @Mock + NetconfAccessor netconfAccessor; + @Mock + VESCollectorService vesCollectorService; + @Mock + VESCollectorCfgService vesCfgService; + + private final int SEQUENCE_NO = 10; + + @Test + public void test() { + String dateTimeString = "2020-02-05T12:30:45.283Z"; + String name = "Slot-0"; + + when(netconfAccessor.getNodeId()).thenReturn(new NodeId("nSky")); + when(netconfAccessor.getNetconfNode()).thenReturn(new TestNetconfNode()); + when(vesCollectorService.getConfig()).thenReturn(vesCfgService); + when(vesCfgService.getReportingEntityName()).thenReturn("SDN-R"); + Component testComponent = ComponentHelper.get(name, dateTimeString); + + ORanRegistrationToVESpnfRegistrationMapper mapper = new ORanRegistrationToVESpnfRegistrationMapper(netconfAccessor, vesCollectorService, testComponent); + mapper.mapCommonEventHeader(SEQUENCE_NO); + mapper.mapPNFRegistrationFields(); + } + + public class TestNetconfNode implements NetconfNode { + + @Override + public @Nullable Credentials getCredentials() { + return null; + } + + @Override + public @Nullable Host getHost() { + return new Host(new IpAddress(new Ipv4Address("10.10.10.10"))); + } + + @Override + public @Nullable PortNumber getPort() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Boolean isTcpOnly() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Protocol getProtocol() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Boolean isSchemaless() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable YangModuleCapabilities getYangModuleCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable NonModuleCapabilities getNonModuleCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Boolean isReconnectOnChangedSchema() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getConnectionTimeoutMillis() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getDefaultRequestTimeoutMillis() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getMaxConnectionAttempts() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint16 getBetweenAttemptsTimeoutMillis() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable BigDecimal getSleepFactor() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint32 getKeepaliveDelay() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint16 getConcurrentRpcLimit() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable Uint16 getActorResponseWaitTime() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable OdlHelloMessageCapabilities getOdlHelloMessageCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable ConnectionStatus getConnectionStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable ClusteredConnectionStatus getClusteredConnectionStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable String getConnectedMessage() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable AvailableCapabilities getAvailableCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable UnavailableCapabilities getUnavailableCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable PassThrough getPassThrough() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable String getSchemaCacheDirectory() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable YangLibrary getYangLibrary() { + // TODO Auto-generated method stub + return null; + } + + @Override + public @Nullable IgnoreMissingSchemaSources getIgnoreMissingSchemaSources() { + // TODO Auto-generated method stub + return null; + } + + } + +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanToInternalDataModel.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanToInternalDataModel.java index 76b2f32ce..531b2f939 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanToInternalDataModel.java +++ b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/TestORanToInternalDataModel.java @@ -18,64 +18,80 @@ package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test; import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.junit.Assert.assertTrue; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import org.junit.After; -import org.junit.Before; +import java.util.Optional; +import java.util.function.IntConsumer; +import java.util.stream.IntStream; +import org.eclipse.jdt.annotation.Nullable; import org.junit.Test; -import org.mockito.Mockito; import org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl.ORanToInternalDataModel; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.hardware.rev180313.HardwareClass; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.hardware.rev180313.hardware.Component; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; -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.params.xml.ns.yang.data.provider.rev201110.Inventory; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class TestORanToInternalDataModel { - NodeId nodeId; - Component component; + private static final Logger LOG = LoggerFactory.getLogger(TestORanToInternalDataModel.class); - @Before - public void init() throws InterruptedException, IOException { - nodeId = mock(NodeId.class); - component = mock(Component.class); + NodeId nodeId = new NodeId("ORan-1000"); - when(nodeId.getValue()).thenReturn("ORan-1000"); - when(component.getParent()).thenReturn("Shelf"); - when(component.getName()).thenReturn("Slot-0"); - when(component.getParentRelPos()).thenReturn(0); - when(component.getUuid()).thenReturn(new Uuid("0Aabcdef-0abc-0cfD-0abC-0123456789AB")); - - List<String> list = new ArrayList<String>(); - list.add("Card-01A"); - list.add("Card-01B"); - - when(component.getContainsChild()).thenReturn(list); - when(component.getName()).thenReturn("Nokia"); - when(component.getDescription()).thenReturn("ORAN Network Element NO-456"); - Class<? extends HardwareClass> hwClass = TestHardwareClass.class; - Mockito.<Class<? extends HardwareClass>>when(component.getXmlClass()).thenReturn(hwClass); + @Test + public void testInventory() { + String dateTimeString = "2020-02-05T12:30:45.283Z"; + String name = "Slot-0"; - DateAndTime dt = new DateAndTime("2020-02-05T12:30:45.283Z"); - when(component.getMfgDate()).thenReturn(dt); + Component testComponent = ComponentHelper.get(name, dateTimeString); + Optional<Inventory> oInventory = ORanToInternalDataModel.getInternalEquipment(nodeId, testComponent, 0); + assertTrue(oInventory.isPresent()); + Inventory inventory = oInventory.get(); + assertEquals(name, inventory.getUuid()); + assertEquals(dateTimeString, inventory.getDate()); + assertEquals(nodeId.getValue(), inventory.getNodeId()); } @Test - public void test() throws Exception { - ORanToInternalDataModel model = new ORanToInternalDataModel(); - model.getInternalEquipment(nodeId, component,0); - assertEquals(component.getUuid().getValue(), "0Aabcdef-0abc-0cfD-0abC-0123456789AB"); - assertEquals(component.getMfgDate().getValue(), "2020-02-05T12:30:45.283Z"); + public void testInventoryList() throws IOException, ClassNotFoundException { + List<Component> componentList = ComponentHelper.getComponentList("/Device-ietf-hardware-Output.json"); + List<Inventory> inventoryList = ORanToInternalDataModel.getInventoryList(nodeId, componentList); + //componentList.forEach(System.out::println); + assertEquals("All elements", 27, inventoryList.size()); + assertEquals("Fully parseable", componentList.size(), inventoryList.size()); + assertEquals("Treelevel always there", 0, + inventoryList.stream().filter(inventory -> inventory.getTreeLevel() == null).count()); + listAsTree(inventoryList); + } + private void listAsTree(List<Inventory> inventoryList) { + //Walk through complete list and print parameters + IntConsumer action = level -> IntStream.range(0, inventoryList.size()) + .filter(idx -> inventoryList.get(idx).getTreeLevel().intValue() == level) + .forEach(idx2 -> printElements(idx2, level, inventoryList.get(idx2))); + //Walk trough 10 levels + IntStream.range(0, 10) + .forEach(action); } - @After - public void cleanUp() throws Exception { + private void printElements(int idx2, int level, Inventory inventory) { + System.out.println(level + ": " + inventory.getParentUuid() + " " + + inventory.getUuid()); + } + @SuppressWarnings("unused") + private boolean compareLevel(int idx, List<Component> componentList, List<Inventory> inventoryList) { + @Nullable + Integer relPos = componentList.get(idx).getParentRelPos(); + @Nullable + Uint32 treeLevel = inventoryList.get(idx).getTreeLevel(); + LOG.warn("Treelevel relPos: {} treeLevel: {}", relPos, treeLevel); + if (relPos != null && treeLevel != null) { + return relPos == treeLevel.intValue(); + } + return false; } } diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/mock/TransactionUtilsMock.java b/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/mock/TransactionUtilsMock.java deleted file mode 100644 index d23227d7f..000000000 --- a/sdnr/wt/devicemanager-oran/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/test/mock/TransactionUtilsMock.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : ccsdk feature sdnr wt - * ================================================================================================= - * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved. - * ================================================================================================= - * 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. - * ============LICENSE_END========================================================================== - */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.test.mock; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import org.eclipse.jdt.annotation.Nullable; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils; -import org.opendaylight.mdsal.binding.api.DataBroker; -import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class TransactionUtilsMock implements TransactionUtils { - - @Override - public <T extends DataObject> @Nullable T readData(DataBroker dataBroker, LogicalDatastoreType dataStoreType, - InstanceIdentifier<T> iid) { - // TODO Auto-generated method stub - return null; - } - - @Override - public <T extends DataObject> @Nullable T readDataOptionalWithStatus(DataBroker dataBroker, - LogicalDatastoreType dataStoreType, InstanceIdentifier<T> iid, AtomicBoolean noErrorIndication, - AtomicReference<String> statusIndicator) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/sdnr/wt/devicemanager-oran/provider/src/test/resources/Device-ietf-hardware-Output.json b/sdnr/wt/devicemanager-oran/provider/src/test/resources/Device-ietf-hardware-Output.json new file mode 100644 index 000000000..b5728fe1e --- /dev/null +++ b/sdnr/wt/devicemanager-oran/provider/src/test/resources/Device-ietf-hardware-Output.json @@ -0,0 +1,442 @@ +{ + "hardware": { + "component": [ + { + "name": "chassis-temperature-exhaust", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-temperature-exhaust", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 30, + "value-type": "celsius", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "chassis", + "parent-rel-pos": 0 + }, + { + "name": "slot0-logical0-rrh", + "state": { + "oper-state": "enabled", + "admin-state": "unlocked" + }, + "model-name": "FTLX1475D3BTL-E7", + "mfg-name": "FINISAR CORP.", + "alias": "Slot0-A-rrh", + "class": "iana-hardware:port", + "contains-child": [ + "slot0-logical0-rrh-temperature" + ], + "parent": "slot0-logical0", + "o-ran-hardware:o-ran-name": "slot0-logical0-rrh", + "serial-num": "AYR3GA9", + "parent-rel-pos": 1 + }, + { + "name": "slot2-logical2", + "state": { + "oper-state": "disabled", + "admin-state": "unlocked" + }, + "alias": "Slot3-B", + "class": "iana-hardware:module", + "parent": "slot2", + "description": "SLOT3-B", + "parent-rel-pos": 3 + }, + { + "name": "chassis-temperature-inlet", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-temperature-inlet", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 29, + "value-type": "celsius", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "chassis", + "parent-rel-pos": 1 + }, + { + "name": "chassis-fan2", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan2", + "class": "iana-hardware:fan", + "contains-child": [ + "chassis-fan2-speed" + ], + "parent": "chassis", + "parent-rel-pos": 4 + }, + { + "name": "slot0-logical0-bbu-temperature", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "Slot0-A-bbu-temperature", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 37, + "value-type": "celsius", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "slot0-logical0-bbu", + "parent-rel-pos": 0 + }, + { + "name": "chassis-fan3", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan3", + "class": "iana-hardware:fan", + "contains-child": [ + "chassis-fan3-speed" + ], + "parent": "chassis", + "parent-rel-pos": 5 + }, + { + "name": "chassis-fan0", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan0", + "class": "iana-hardware:fan", + "contains-child": [ + "chassis-fan0-speed" + ], + "parent": "chassis", + "parent-rel-pos": 2 + }, + { + "name": "slot0-logical1", + "state": { + "oper-state": "disabled", + "admin-state": "unlocked" + }, + "alias": "Slot0-B", + "class": "iana-hardware:module", + "parent": "slot0", + "description": "SLOT0-B", + "parent-rel-pos": 2 + }, + { + "name": "chassis-fan1", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan1", + "class": "iana-hardware:fan", + "contains-child": [ + "chassis-fan1-speed" + ], + "parent": "chassis", + "parent-rel-pos": 3 + }, + { + "name": "slot0-logical0", + "state": { + "oper-state": "enabled", + "admin-state": "unlocked" + }, + "alias": "Slot0-A", + "class": "iana-hardware:module", + "contains-child": [ + "slot0-logical0-rrh", + "slot0-logical0-bbu" + ], + "parent": "slot0", + "description": "SLOT0-AZ", + "parent-rel-pos": 1 + }, + { + "name": "slot0-logical2", + "state": { + "oper-state": "disabled", + "admin-state": "unlocked" + }, + "alias": "Slot0-C", + "class": "iana-hardware:module", + "parent": "slot0", + "description": "SLOT0-C", + "parent-rel-pos": 3 + }, + { + "name": "chassis-fan1-speed", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan1-speed", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 4100, + "value-type": "rpm", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "chassis-fan1", + "parent-rel-pos": 0 + }, + { + "name": "slot2-logical1", + "state": { + "oper-state": "disabled", + "admin-state": "unlocked" + }, + "alias": "Slot3-A", + "class": "iana-hardware:module", + "parent": "slot2", + "description": "SLOT3-A", + "parent-rel-pos": 2 + }, + { + "name": "slot2-logical0", + "state": { + "oper-state": "disabled", + "admin-state": "unlocked" + }, + "alias": "Slot2-C", + "class": "iana-hardware:module", + "parent": "slot2", + "description": "SLOT2-C", + "parent-rel-pos": 1 + }, + { + "name": "cpu-temperature", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "cpu-temperature", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 30, + "value-type": "celsius", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "cpu", + "parent-rel-pos": 0 + }, + { + "name": "chassis", + "state": { + "oper-state": "enabled", + "admin-state": "unlocked" + }, + "model-name": "ProteusCPRI Compact", + "mfg-name": "ISCO", + "alias": "chassis", + "class": "iana-hardware:chassis", + "contains-child": [ + "chassis-temperature-inlet", + "cpu", + "chassis-fan0", + "chassis-temperature-exhaust", + "slot0", + "slot2", + "chassis-fan3", + "chassis-fan2", + "chassis-fan1" + ], + "serial-num": "10283", + "description": "HighStreet-ONAP40", + "software-rev": "3.8.1 (2020-10-30 11:47:59)" + }, + { + "name": "slot0-logical0-bbu", + "state": { + "oper-state": "enabled", + "admin-state": "unlocked" + }, + "model-name": "FTLX1475D3BTL-E7", + "mfg-name": "FINISAR CORP.", + "alias": "Slot0-A-bbu", + "class": "iana-hardware:port", + "contains-child": [ + "slot0-logical0-bbu-temperature" + ], + "parent": "slot0-logical0", + "o-ran-hardware:o-ran-name": "slot0-logical0-bbu", + "serial-num": "AYR3GA2", + "parent-rel-pos": 0 + }, + { + "name": "slot2", + "state": { + "oper-state": "enabled", + "admin-state": "unlocked" + }, + "model-name": "385A-SFP-2P-40-FHL-JC3", + "alias": "slot2", + "class": "iana-hardware:module", + "contains-child": [ + "slot2-temperature", + "slot2-logical0", + "slot2-logical1", + "slot2-logical2" + ], + "parent": "chassis", + "firmware-rev": "12.00.42-S (0F7F1001)", + "serial-num": "7220718", + "parent-rel-pos": 9, + "software-rev": "0" + }, + { + "name": "chassis-fan0-speed", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan0-speed", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 4100, + "value-type": "rpm", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "chassis-fan0", + "parent-rel-pos": 0 + }, + { + "name": "slot0", + "state": { + "oper-state": "enabled", + "admin-state": "unlocked" + }, + "model-name": "385A-SFP-2P-40-FHL-JC3", + "alias": "slot0", + "class": "iana-hardware:module", + "contains-child": [ + "slot0-logical0", + "slot0-logical2", + "slot0-temperature", + "slot0-logical1" + ], + "parent": "chassis", + "firmware-rev": "12.00.42-S (0F7F1001)", + "serial-num": "7220530", + "parent-rel-pos": 7, + "software-rev": "0" + }, + { + "name": "slot0-temperature", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "slot0-temperature", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 51, + "value-type": "celsius", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "slot0", + "parent-rel-pos": 0 + }, + { + "name": "cpu", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "cpu", + "class": "iana-hardware:cpu", + "contains-child": [ + "cpu-temperature" + ], + "parent": "chassis", + "parent-rel-pos": 6 + }, + { + "name": "slot0-logical0-rrh-temperature", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "Slot0-A-rrh-temperature", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 35, + "value-type": "celsius", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "slot0-logical0-rrh", + "parent-rel-pos": 0 + }, + { + "name": "chassis-fan3-speed", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan3-speed", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 1000, + "value-type": "rpm", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "chassis-fan3", + "parent-rel-pos": 0 + }, + { + "name": "chassis-fan2-speed", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "chassis-fan2-speed", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 4100, + "value-type": "rpm", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "chassis-fan2", + "parent-rel-pos": 0 + }, + { + "name": "slot2-temperature", + "state": { + "oper-state": "enabled", + "admin-state": "locked" + }, + "alias": "slot2-temperature", + "sensor-data": { + "value-timestamp": "2021-02-18T12:11:03.5Z", + "value": 49, + "value-type": "celsius", + "oper-status": "ok" + }, + "class": "iana-hardware:sensor", + "parent": "slot2", + "parent-rel-pos": 0 + } + ] + } +}
\ No newline at end of file diff --git a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/NotificationProxyParser.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/NotificationProxyParser.java new file mode 100644 index 000000000..ea16f20bb --- /dev/null +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/NotificationProxyParser.java @@ -0,0 +1,49 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.service; + +import java.time.Instant; +import java.util.HashMap; +import org.opendaylight.yangtools.yang.binding.Notification; + +public interface NotificationProxyParser { + + /** + * parses the Notification proxy object created by ODL + * Returns a Map with class members as keys and the member values as values. + * The keys are in xpath notation. + * Ex: key = /notification/VALUECHANGE[@xmlns=\"urn:org:onap:ccsdk:features:sdnr:northbound:onecell-notification\"]/device/device-info/serial-number" + * value = "0005B94238A0" + * References: https://stackoverflow.com/questions/19633534/what-is-com-sun-proxy-proxy + */ + public HashMap<String, String> parseNotificationProxy(Notification notification); + + /** + * Gets the time at which the Event occurred if the notification is an instance of EventInstantAware. If not, then returns the current time + * Read notification time via {@link #EventInstantAware } interface. + * + * @param notification + * @return + */ + public Instant getTime(Notification notification); + +} diff --git a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorCfgService.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorCfgService.java index c274ff91c..5025b5bba 100644 --- a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorCfgService.java +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorCfgService.java @@ -21,9 +21,18 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.service; +/* + * Interface that exposes a subset of the VES Collector configuration properties to clients that require them + */ + public interface VESCollectorCfgService { + /* gets the reportingEntityName (REPORTING_ENTITY_NAME) configured in the etc/devicemanager.properties configuration file */ String getReportingEntityName(); + + /* gets the log detail configuration (EVENTLOG_MSG_DETAIL) property value configured in the etc/devicemanager.properties configuration file */ String getEventLogMsgDetail(); + + /* gets the VES Collector enabled property (VES_COLLECTOR_ENABLED) value configured in the etc/devicemanager.properties configuration file */ boolean isVESCollectorEnabled(); } diff --git a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorService.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorService.java index 287f0f622..f93b599bf 100644 --- a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorService.java +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESCollectorService.java @@ -21,7 +21,13 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.service; - +import com.fasterxml.jackson.core.JsonProcessingException; +import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; /** * Interface used for publishing VES messages to the VES Collector @@ -31,9 +37,64 @@ package org.onap.ccsdk.features.sdnr.wt.devicemanager.service; */ public interface VESCollectorService extends DeviceManagerService { + /** + * Gets the VES Collector configuration from etc/devicemanager.properties configuration file + */ VESCollectorCfgService getConfig(); - boolean publishVESMessage(String vesMsg); - public void registerForChanges(VESCollectorConfigChangeListener o); - public void deregister(VESCollectorConfigChangeListener o); + + /** + * publishes a VES message to the VES Collector by sending a REST request + * @param vesMsg + * @return + */ + boolean publishVESMessage(VESMessage vesMsg); + + /** + * clients interested in VES Collector configuration changes can call the registerForChanges method so as to be notified when configuration changes are made + */ + void registerForChanges(VESCollectorConfigChangeListener o); + + /** + * de-registering clients as part of cleanup + * @param o + */ + void deregister(VESCollectorConfigChangeListener o); + + /** + * Get a parser to parse {@link #org.opendaylight.yangtools.yang.binding.Notification } messages + * @return NotificationProxyParser object + */ + @NonNull + NotificationProxyParser getNotificationProxyParser(); + + /** + * Generates VES Event JSON containing commonEventHeader and notificationFields fields + * + * @param commonEventHeader + * @param notifFields + * @return VESMessage - representing the VESEvent JSON + * @throws JsonProcessingException + */ + VESMessage generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, VESNotificationFieldsPOJO notifFields) throws JsonProcessingException; + + /** + * Generates VES Event JSON containing commonEventHeader and faultFields fields + * + * @param commonEventHeader + * @param faultFields + * @return VESMessage - representing the VES Event JSON + * @throws JsonProcessingException + */ + VESMessage generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, VESFaultFieldsPOJO faultFields) throws JsonProcessingException; + + /** + * Generates VES Event JSON containing commonEventHeader and pnfRegistration fields + * + * @param commonEventHeader + * @param faultFields + * @return VESMessage - representing the VES Event JSON + * @throws JsonProcessingException + */ + VESMessage generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, VESPNFRegistrationFieldsPOJO faultFields) throws JsonProcessingException; } diff --git a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESEventMapper.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESEventMapper.java new file mode 100644 index 000000000..76c8305a2 --- /dev/null +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/service/VESEventMapper.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; +import org.opendaylight.yangtools.yang.binding.Notification; + +/* + * Interface for mapping ODL notification to VES event fields grouped by event type. + * Also includes the commonEventHeader which is applicable for all events. + * Ex: fault event, notification event. + * + * No base implementation exists for this interface. Clients that need to map their data into VES formats must implement this interface. + */ + +public abstract class VESEventMapper<N extends Notification,F extends Notification,T extends Notification> { + + /** + * Creates VESEvent mapping + */ + public abstract String createMapping(NetconfBindingAccessor netconfAccessor, + VESCollectorService vesCollectorService, Notification notification, String notifName, int sequenceNo, + Instant eventTime); + + /** + * Returns VES commonEventHeader fields + */ + public abstract VESCommonEventHeaderPOJO mapCommonEventHeader(N notification); + + /** + * Returns VES faultFields + */ + public abstract VESFaultFieldsPOJO mapFaultFields(F notification); + + /** + * Returns VES Notification Fields + */ + public abstract VESNotificationFieldsPOJO mapNotificationFields(T notification); + + /** + * Returns VES pnfRegistration domain fields + * + * @return + */ + public abstract VESPNFRegistrationFieldsPOJO mapPNFRegistrationFields(); + + /** + * Generates VES Event JSON containing commonEventHeader and notificationFields fields + * + * @param commonEventHeader + * @param notifFields + * @return String - representing the VESEvent JSON + */ + String generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, VESNotificationFieldsPOJO notifFields) { + Map<String, Object> innerEvent = new HashMap<String, Object>(); + innerEvent.put("commonEventHeader", commonEventHeader); + innerEvent.put("notificationFields", notifFields); + + Map<String, Object> outerEvent = new HashMap<String, Object>(); + outerEvent.put("event", innerEvent); + try { + ObjectMapper objMapper = new ObjectMapper(); + return objMapper.writeValueAsString(outerEvent); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Generates VES Event JSON containing commonEventHeader and faultFields fields + * + * @param commonEventHeader + * @param faultFields + * @return String - representing the VES Event JSON + */ + String generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, VESFaultFieldsPOJO faultFields) { + Map<String, Object> innerEvent = new HashMap<String, Object>(); + innerEvent.put("commonEventHeader", commonEventHeader); + innerEvent.put("faultFields", faultFields); + + Map<String, Object> outerEvent = new HashMap<String, Object>(); + outerEvent.put("event", innerEvent); + try { + ObjectMapper objMapper = new ObjectMapper(); + return objMapper.writeValueAsString(outerEvent); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESCommonEventHeaderPOJO.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESCommonEventHeaderPOJO.java index 730c63b0f..db76b84c7 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESCommonEventHeaderPOJO.java +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESCommonEventHeaderPOJO.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.types; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonPropertyOrder; diff --git a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESFaultFieldsPOJO.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESFaultFieldsPOJO.java new file mode 100644 index 000000000..0f40ed3a4 --- /dev/null +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESFaultFieldsPOJO.java @@ -0,0 +1,111 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.types; + +import java.util.HashMap; + +public class VESFaultFieldsPOJO { + + //fault domain Fields + private String alarmCondition = ""; + private String alarmInterfaceA = ""; + private String eventCategory = ""; + private String eventSeverity = ""; + private String eventSourceType = ""; + private String faultFieldsVersion = "4.0"; + private String specificProblem = ""; + private String vfStatus = ""; + private HashMap<String, Object> alarmAdditionalInformation = new HashMap<String, Object>(); + + public String getAlarmCondition() { + return alarmCondition; + } + + public void setAlarmCondition(String alarmCondition) { + this.alarmCondition = alarmCondition; + } + + public String getAlarmInterfaceA() { + return alarmInterfaceA; + } + + public void setAlarmInterfaceA(String alarmInterfaceA) { + this.alarmInterfaceA = alarmInterfaceA; + } + + public String getEventCategory() { + return eventCategory; + } + + public void setEventCategory(String eventCategory) { + this.eventCategory = eventCategory; + } + + public String getEventSeverity() { + return eventSeverity; + } + + public void setEventSeverity(String eventSeverity) { + this.eventSeverity = eventSeverity; + } + + public String getEventSourceType() { + return eventSourceType; + } + + public void setEventSourceType(String eventSourceType) { + this.eventSourceType = eventSourceType; + } + + public String getFaultFieldsVersion() { + return faultFieldsVersion; + } + + public void setFaultFieldsVersion(String faultFieldsVersion) { + this.faultFieldsVersion = faultFieldsVersion; + } + + public String getSpecificProblem() { + return specificProblem; + } + + public void setSpecificProblem(String specificProblem) { + this.specificProblem = specificProblem; + } + + public String getVfStatus() { + return vfStatus; + } + + public void setVfStatus(String vfStatus) { + this.vfStatus = vfStatus; + } + + public HashMap<String, Object> getAlarmAdditionalInformation() { + return alarmAdditionalInformation; + } + + public void setAlarmAdditionalInformation(HashMap<String, Object> alarmAdditionalInformation) { + this.alarmAdditionalInformation = alarmAdditionalInformation; + } + +} diff --git a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESMessage.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESMessage.java new file mode 100644 index 000000000..2c5266f97 --- /dev/null +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESMessage.java @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.types; + +public class VESMessage { + + private String message; + + public VESMessage(String vesMessage) { + this.message = vesMessage; + } + + public String getMessage() { + return message; + } +} diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESNotificationFieldsPOJO.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESNotificationFieldsPOJO.java index 09aa6dd0a..6beb04751 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/VESNotificationFieldsPOJO.java +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESNotificationFieldsPOJO.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.types; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @@ -113,4 +113,4 @@ public class VESNotificationFieldsPOJO { } -} +}
\ No newline at end of file diff --git a/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESPNFRegistrationFieldsPOJO.java b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESPNFRegistrationFieldsPOJO.java new file mode 100644 index 000000000..e564914da --- /dev/null +++ b/sdnr/wt/devicemanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/types/VESPNFRegistrationFieldsPOJO.java @@ -0,0 +1,148 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.devicemanager.types; + +import java.util.HashMap; +import java.util.Map; + +public class VESPNFRegistrationFieldsPOJO { + + private Map<String, String> additionalFields = new HashMap<String, String>(); + private String lastServiceDate = ""; + private String macAddress = ""; + private String manufactureDate = ""; + private String modelNumber = ""; + private String oamV4IpAddress = ""; + private String oamV6IpAddress = ""; + private String pnfRegistrationFieldsVersion = "2.0"; + private String serialNumber = ""; + private String softwareVersion = ""; + private String unitFamily = ""; + private String unitType = ""; + private String vendorName = ""; + + public Map<String, String> getAdditionalFields() { + return additionalFields; + } + + public void setAdditionalFields(Map<String, String> additionalFields) { + this.additionalFields = additionalFields; + } + + public String getLastServiceDate() { + return lastServiceDate; + } + + public void setLastServiceDate(String lastServiceDate) { + this.lastServiceDate = lastServiceDate; + } + + public String getMacAddress() { + return macAddress; + } + + public void setMacAddress(String macAddress) { + this.macAddress = macAddress; + } + + public String getManufactureDate() { + return manufactureDate; + } + + public void setManufactureDate(String manufactureDate) { + this.manufactureDate = manufactureDate; + } + + public String getModelNumber() { + return modelNumber; + } + + public void setModelNumber(String modelNumber) { + this.modelNumber = modelNumber; + } + + public String getOamV4IpAddress() { + return oamV4IpAddress; + } + + public void setOamV4IpAddress(String oamV4IpAddress) { + this.oamV4IpAddress = oamV4IpAddress; + } + + public String getOamV6IpAddress() { + return oamV6IpAddress; + } + + public void setOamV6IpAddress(String oamV6IpAddress) { + this.oamV6IpAddress = oamV6IpAddress; + } + + public String getPnfRegistrationFieldsVersion() { + return pnfRegistrationFieldsVersion; + } + + public void setPnfRegistrationFieldsVersion(String pnfRegistrationFieldsVersion) { + this.pnfRegistrationFieldsVersion = pnfRegistrationFieldsVersion; + } + + public String getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public String getSoftwareVersion() { + return softwareVersion; + } + + public void setSoftwareVersion(String softwareVersion) { + this.softwareVersion = softwareVersion; + } + + public String getUnitFamily() { + return unitFamily; + } + + public void setUnitFamily(String unitFamily) { + this.unitFamily = unitFamily; + } + + public String getUnitType() { + return unitType; + } + + public void setUnitType(String unitType) { + this.unitType = unitType; + } + + public String getVendorName() { + return vendorName; + } + + public void setVendorName(String vendorName) { + this.vendorName = vendorName; + + } + +} diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java index fd2929f1a..689336f5e 100644 --- a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/DeviceManagerImpl.java @@ -75,14 +75,14 @@ import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationService import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.PerformanceManager; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; import org.onap.ccsdk.features.sdnr.wt.devicemanager.toggleAlarmFilter.DevicemanagerNotificationDelayService; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.VESCollectorClient; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.VESCollectorServiceImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketmanagerService; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.MountPointService; import org.opendaylight.mdsal.binding.api.NotificationPublishService; import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.websocketmanager.rev150105.WebsocketmanagerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -125,7 +125,7 @@ public class DeviceManagerImpl implements NetconfNetworkElementService, DeviceMa private ConnectionStatusHousekeepingService housekeepingService; private NetconfNodeStateService netconfNodeStateService; private DataProvider dataProvider; - private VESCollectorClient vesCollectorClient; + private VESCollectorServiceImpl vesCollectorServiceImpl; // Handler private DeviceManagerNetconfConnectHandler deviceManagerNetconfConnectHandler; @@ -209,7 +209,7 @@ public class DeviceManagerImpl implements NetconfNetworkElementService, DeviceMa this.aaiProviderClient = new AaiProviderClient(config, this); - this.vesCollectorClient = new VESCollectorClient(config); + this.vesCollectorServiceImpl = new VESCollectorServiceImpl(config); // EM String myDbKeyNameExtended = MYDBKEYNAMEBASE + "-" + esConfig.getCluster(); @@ -273,13 +273,13 @@ public class DeviceManagerImpl implements NetconfNetworkElementService, DeviceMa close(archiveCleanService); close(housekeepingService); close(deviceManagerNetconfConnectHandler); - close(vesCollectorClient); + close(vesCollectorServiceImpl); LOG.info("DeviceManagerImpl closing done"); } @Override public @NonNull <L extends NetworkElementFactory> FactoryRegistration<L> registerBindingNetworkElementFactory( - @NonNull L factory) { + @NonNull final L factory) { LOG.info("Factory registration {}", factory.getClass().getName()); factoryList.add(factory); @@ -416,7 +416,7 @@ public class DeviceManagerImpl implements NetconfNetworkElementService, DeviceMa @Override public @NonNull VESCollectorService getVESCollectorService() { - return this.vesCollectorClient; + return this.vesCollectorServiceImpl; } } diff --git a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotificationMapper.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NotificationProxyParserImpl.java index ccb1ac098..802c05d0c 100644 --- a/sdnr/wt/devicemanager-oran/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/oran/impl/ORanNotificationMapper.java +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/impl/util/NotificationProxyParserImpl.java @@ -19,7 +19,8 @@ * ============LICENSE_END========================================================= * */ -package org.onap.ccsdk.features.sdnr.wt.devicemanager.oran.impl; +package org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util; + import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -29,6 +30,7 @@ import java.time.Instant; import java.util.HashMap; import java.util.List; import org.eclipse.jdt.annotation.NonNull; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; import org.opendaylight.yangtools.concepts.Identifier; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.EventInstantAware; @@ -38,7 +40,8 @@ import org.opendaylight.yangtools.yang.common.QName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ORanNotificationMapper { +public class NotificationProxyParserImpl implements NotificationProxyParser { + /* * Converter of TR069 notifications to VES key, value hashmap. @@ -111,10 +114,11 @@ public class ORanNotificationMapper { * } * */ - private static final Logger log = LoggerFactory.getLogger(ORanNotificationMapper.class); + private static final Logger log = LoggerFactory.getLogger(NotificationProxyParserImpl.class); private Notification notification; - public HashMap<String, String> performMapping(Notification notification) + @Override + public HashMap<String, String> parseNotificationProxy(Notification notification) /*throws ORanNotificationMapperException*/ { try { @@ -271,7 +275,7 @@ public class ORanNotificationMapper { * Inspiration from KebabCaseStrategy class of com.fasterxml.jackson.databind with an additional condition to handle numbers as well * Using QNAME would have been a more fool proof solution, however it can lead to performance problems due to usage of Java reflection */ - public String convertCamelToKebabCase(String input) + private String convertCamelToKebabCase(String input) { if (input == null) return input; // garbage in, garbage out int length = input.length(); @@ -324,7 +328,7 @@ public class ORanNotificationMapper { throw new IllegalArgumentException("indentifiable object without key"); } - public Instant getTime(Notification notification2) { + public Instant getTime(Notification notification) { @NonNull Instant time; if (notification instanceof EventInstantAware) { // If notification class extends/implements the EventInstantAware diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/VESCollectorClient.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/VESCollectorServiceImpl.java index 70ff86009..47ac9c785 100644 --- a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/VESCollectorClient.java +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/VESCollectorServiceImpl.java @@ -21,6 +21,8 @@ */ package org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.ArrayList; import java.util.Base64; @@ -28,31 +30,42 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; import org.onap.ccsdk.features.sdnr.wt.common.configuration.filechange.IConfigChangedListener; import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient; import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPResponse; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.impl.util.NotificationProxyParserImpl; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NotificationProxyParser; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorConfigChangeListener; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESFaultFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESPNFRegistrationFieldsPOJO; import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.config.VESCollectorCfgImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VESCollectorClient implements VESCollectorService, IConfigChangedListener, AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(VESCollectorClient.class); +public class VESCollectorServiceImpl implements VESCollectorService, IConfigChangedListener, AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(VESCollectorServiceImpl.class); private final VESCollectorCfgImpl vesConfig; private final ConfigurationFileRepresentation cfg; private BaseHTTPClient httpClient; private final Map<String, String> headerMap; private List<VESCollectorConfigChangeListener> registeredObjects; + private final ObjectMapper objMapper; - public VESCollectorClient(ConfigurationFileRepresentation config) { + + public VESCollectorServiceImpl(ConfigurationFileRepresentation config) { registeredObjects = new ArrayList<VESCollectorConfigChangeListener>(); this.vesConfig = new VESCollectorCfgImpl(config); this.cfg = config; this.cfg.registerConfigChangedListener(this); + this.objMapper = new ObjectMapper(); - httpClient = new BaseHTTPClient(getBaseUrl()); + httpClient = new BaseHTTPClient(getBaseUrl(), this.vesConfig.isTrustAllCerts()); this.headerMap = new HashMap<>(); this.headerMap.put("Content-Type", "application/json"); @@ -84,15 +97,13 @@ public class VESCollectorClient implements VESCollectorService, IConfigChangedLi } - - @Override - public boolean publishVESMessage(String message) { - LOG.info("In VESClient - {} ", message); + public boolean publishVESMessage(VESMessage message) { + LOG.info("In VESClient - {} ", message.getMessage()); BaseHTTPResponse response; try { String uri = "eventListener" + "/" + getConfig().getVersion(); - response = httpClient.sendRequest(uri, "POST", message, headerMap); + response = httpClient.sendRequest(uri, "POST", message.getMessage(), headerMap); LOG.debug("finished with responsecode {}", response.code); return response.code == 200; } catch (IOException e) { @@ -109,7 +120,8 @@ public class VESCollectorClient implements VESCollectorService, IConfigChangedLi @Override public void onConfigChanged() { - httpClient.setBaseUrl(getBaseUrl()); + LOG.debug("In onConfigChanged - isTrustAllCerts = {} getBaseUrl = {}", getConfig().isTrustAllCerts(), getBaseUrl()); + httpClient = new BaseHTTPClient(getBaseUrl(), this.vesConfig.isTrustAllCerts()); setAuthorization(getConfig().getUsername(), getConfig().getPassword()); Iterator<VESCollectorConfigChangeListener> it = registeredObjects.iterator(); while (it.hasNext()) { @@ -128,4 +140,68 @@ public class VESCollectorClient implements VESCollectorService, IConfigChangedLi registeredObjects.remove(o); } + @Override + public @NonNull NotificationProxyParser getNotificationProxyParser() { + return new NotificationProxyParserImpl(); + } + + /** + * Generates VES Event JSON containing commonEventHeader and notificationFields fields + * + * @param commonEventHeader + * @param notifFields + * @return VESMessage - representing the VESEvent JSON + * @throws JsonProcessingException + */ + @Override + public VESMessage generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, + VESNotificationFieldsPOJO notifFields) throws JsonProcessingException { + Map<String, Object> innerEvent = new HashMap<String, Object>(); + innerEvent.put("commonEventHeader", commonEventHeader); + innerEvent.put("notificationFields", notifFields); + + Map<String, Object> outerEvent = new HashMap<String, Object>(); + outerEvent.put("event", innerEvent); + LOG.info("in generateVESEvent - {}", objMapper.writeValueAsString(outerEvent)); + return new VESMessage(objMapper.writeValueAsString(outerEvent)); + } + + /** + * Generates VES Event JSON containing commonEventHeader and faultFields fields + * + * @param commonEventHeader + * @param faultFields + * @return VESMessage - representing the VES Event JSON + * @throws JsonProcessingException + */ + @Override + public VESMessage generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, VESFaultFieldsPOJO faultFields) throws JsonProcessingException { + Map<String, Object> innerEvent = new HashMap<String, Object>(); + innerEvent.put("commonEventHeader", commonEventHeader); + innerEvent.put("faultFields", faultFields); + + Map<String, Object> outerEvent = new HashMap<String, Object>(); + outerEvent.put("event", innerEvent); + return new VESMessage(objMapper.writeValueAsString(outerEvent)); + } + + /** + * Generates VES Event JSON containing commonEventHeader and pnfRegistration fields + * + * @param commonEventHeader + * @param pnfRegistrationFields + * @return VESMessage - representing the VES Event JSON + * @throws JsonProcessingException + */ + @Override + public VESMessage generateVESEvent(VESCommonEventHeaderPOJO commonEventHeader, VESPNFRegistrationFieldsPOJO pnfRegistrationFields) throws JsonProcessingException { + Map<String, Object> innerEvent = new HashMap<String, Object>(); + innerEvent.put("commonEventHeader", commonEventHeader); + innerEvent.put("pnfRegistration", pnfRegistrationFields); + + Map<String, Object> outerEvent = new HashMap<String, Object>(); + outerEvent.put("event", innerEvent); + return new VESMessage(objMapper.writeValueAsString(outerEvent)); + } + } diff --git a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/config/VESCollectorCfgImpl.java b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/config/VESCollectorCfgImpl.java index c3bddc9b1..105b915c7 100644 --- a/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/config/VESCollectorCfgImpl.java +++ b/sdnr/wt/devicemanager/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/vescollectorconnector/impl/config/VESCollectorCfgImpl.java @@ -40,6 +40,7 @@ public class VESCollectorCfgImpl implements VESCollectorCfgService, Configuratio private static final String DEFAULT_VALUE_VES_COLLECTOR_PORT = "8080"; private static final String PROPERTY_KEY_VES_COLLECTOR_TLS_ENABLED = "VES_COLLECTOR_TLS_ENABLED"; + private static final String PROPERTY_KEY_VES_COLLECTOR_TRUST_ALL_CERTS = "VES_COLLECTOR_TRUST_ALL_CERTS"; private static final String PROPERTY_KEY_VES_COLLECTOR_USERNAME = "VES_COLLECTOR_USERNAME"; private static final String DEFAULT_VALUE_VES_COLLECTOR_USERNAME = "sample1"; @@ -109,10 +110,15 @@ public class VESCollectorCfgImpl implements VESCollectorCfgService, Configuratio return configuration.getProperty(SECTION_MARKER, PROPERTY_KEY_VES_COLLECTOR_VERSION); } + public boolean isTrustAllCerts() { + return configuration.getPropertyBoolean(SECTION_MARKER, PROPERTY_KEY_VES_COLLECTOR_TRUST_ALL_CERTS); + } + @Override public synchronized void defaults() { configuration.setPropertyIfNotAvailable(SECTION_MARKER, PROPERTY_KEY_VES_COLLECTOR_ENABLED, DEFAULT_VALUE_VES_COLLECTOR_ENABLED); configuration.setPropertyIfNotAvailable(SECTION_MARKER, PROPERTY_KEY_VES_COLLECTOR_TLS_ENABLED, Boolean.FALSE); + configuration.setPropertyIfNotAvailable(SECTION_MARKER, PROPERTY_KEY_VES_COLLECTOR_TRUST_ALL_CERTS, Boolean.FALSE); configuration.setPropertyIfNotAvailable(SECTION_MARKER, PROPERTY_KEY_VES_COLLECTOR_USERNAME, DEFAULT_VALUE_VES_COLLECTOR_USERNAME); configuration.setPropertyIfNotAvailable(SECTION_MARKER, PROPERTY_KEY_VES_COLLECTOR_PASSWORD, diff --git a/sdnr/wt/devicemanager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/test/TestVESCollectorClient.java b/sdnr/wt/devicemanager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/test/TestVESCollectorClient.java index 99e7d7bf9..1ff8efafb 100644 --- a/sdnr/wt/devicemanager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/test/TestVESCollectorClient.java +++ b/sdnr/wt/devicemanager/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/devicemanager/test/TestVESCollectorClient.java @@ -29,7 +29,8 @@ import java.nio.charset.StandardCharsets; import org.junit.After; import org.junit.Test; import org.onap.ccsdk.features.sdnr.wt.common.configuration.ConfigurationFileRepresentation; -import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.VESCollectorClient; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.vescollectorconnector.impl.VESCollectorServiceImpl; public class TestVESCollectorClient { @@ -41,17 +42,17 @@ public class TestVESCollectorClient { + "VES_COLLECTOR_PORT=8080\n" + "VES_COLLECTOR_TLS_ENABLED=true\n" + "VES_COLLECTOR_USERNAME=sample1\n" + "VES_COLLECTOR_PASSWORD=sample1\n" + "VES_COLLECTOR_VERSION=v7\n" + "REPORTING_ENTITY_NAME=ONAP SDN-R\n" + ""; - private static final String message = "Test Message"; + private static final VESMessage message = new VESMessage("Test Message"); private static final String CONFIG_FILE = "test.properties"; @Test public void testNoAuth() throws Exception { ConfigurationFileRepresentation vesCfg; - VESCollectorClient vesClient; + VESCollectorServiceImpl vesClient; Files.asCharSink(new File(CONFIG_FILE), StandardCharsets.UTF_8).write(TESTCONFIG_CONTENT_NO_AUTH); vesCfg = new ConfigurationFileRepresentation(CONFIG_FILE); - vesClient = new VESCollectorClient(vesCfg); + vesClient = new VESCollectorServiceImpl(vesCfg); vesClient.publishVESMessage(message); vesClient.close(); @@ -61,12 +62,12 @@ public class TestVESCollectorClient { @Test public void testAuth() throws Exception { ConfigurationFileRepresentation vesCfg; - VESCollectorClient vesClient; + VESCollectorServiceImpl vesClient; Files.asCharSink(new File("test.properties"), StandardCharsets.UTF_8).write(TESTCONFIG_CONTENT_AUTH); vesCfg = new ConfigurationFileRepresentation("test.properties"); - vesClient = new VESCollectorClient(vesCfg); + vesClient = new VESCollectorServiceImpl(vesCfg); vesClient.publishVESMessage(message); vesClient.close(); } diff --git a/sdnr/wt/mountpoint-registrar/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointregistrar/impl/PNFMountPointClient.java b/sdnr/wt/mountpoint-registrar/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointregistrar/impl/PNFMountPointClient.java index 22b4e5f22..029ae4c55 100644 --- a/sdnr/wt/mountpoint-registrar/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointregistrar/impl/PNFMountPointClient.java +++ b/sdnr/wt/mountpoint-registrar/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointregistrar/impl/PNFMountPointClient.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.Base64; import java.util.HashMap; import java.util.Map; +import org.onap.ccsdk.features.sdnr.wt.common.database.requests.BaseRequest; import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient; import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPResponse; import org.slf4j.Logger; @@ -128,7 +129,7 @@ public class PNFMountPointClient extends BaseHTTPClient { LOG.info("In pnfRequest - {} : {} : {}", pnfName, method, message); BaseHTTPResponse response; try { - String uri = MOUNTPOINT_URI + pnfName; + String uri = MOUNTPOINT_URI + BaseRequest.urlEncodeValue(pnfName); response = this.sendRequest(uri, method, message, headerMap); LOG.debug("finished with responsecode {}", response.code); return response.code; diff --git a/sdnr/wt/mountpoint-state-provider/provider/pom.xml b/sdnr/wt/mountpoint-state-provider/provider/pom.xml index f07a82d68..fc6d7e07e 100644 --- a/sdnr/wt/mountpoint-state-provider/provider/pom.xml +++ b/sdnr/wt/mountpoint-state-provider/provider/pom.xml @@ -107,11 +107,6 @@ <artifactId>org.osgi.compendium</artifactId> <scope>provided</scope> </dependency> - <dependency> - <groupId>org.onap.dmaap.messagerouter.dmaapclient</groupId> - <artifactId>dmaapClient</artifactId> - <version>1.1.12</version> - </dependency> </dependencies> <build> diff --git a/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStatePublisher.java b/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStatePublisher.java index e05b3f1ba..e430a5e24 100644 --- a/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStatePublisher.java +++ b/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStatePublisher.java @@ -29,6 +29,7 @@ import org.eclipse.jdt.annotation.NonNull; import org.json.JSONObject; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,8 +67,8 @@ public class MountpointStatePublisher implements Runnable { } - public String createVESMessage(JSONObject msg, VESCollectorCfgService vesCfg) { - MountpointStateVESMessageFormatter vesFormatter = new MountpointStateVESMessageFormatter(vesCfg); + public VESMessage createVESMessage(JSONObject msg, VESCollectorCfgService vesCfg) { + MountpointStateVESMessageFormatter vesFormatter = new MountpointStateVESMessageFormatter(vesCfg, vesCollectorService); return vesFormatter.createVESMessage(msg); } @@ -77,7 +78,7 @@ public class MountpointStatePublisher implements Runnable { try { if (!getStateObjects().isEmpty()) { JSONObject obj = ((LinkedList<JSONObject>) getStateObjects()).removeFirst(); - String vesMsg = createVESMessage(obj, vesCollectorService.getConfig()); + VESMessage vesMsg = createVESMessage(obj, vesCollectorService.getConfig()); this.vesCollectorService.publishVESMessage(vesMsg); } else { pauseThread(); diff --git a/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStateVESMessageFormatter.java b/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStateVESMessageFormatter.java index 4ab1a9a85..01a8d49ff 100644 --- a/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStateVESMessageFormatter.java +++ b/sdnr/wt/mountpoint-state-provider/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/impl/MountpointStateVESMessageFormatter.java @@ -22,21 +22,27 @@ package org.onap.ccsdk.features.sdnr.wt.mountpointstateprovider.impl; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import java.time.Instant; +import org.eclipse.jdt.annotation.NonNull; import org.json.JSONObject; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESCommonEventHeaderPOJO; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESNotificationFieldsPOJO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MountpointStateVESMessageFormatter { private static final Logger LOG = LoggerFactory.getLogger(MountpointStateVESMessageFormatter.class); - private VESCollectorCfgService vesCfg; + private final @NonNull VESCollectorCfgService vesCfg; + private final @NonNull VESCollectorService vesCollectorService; static long sequenceNo = 0; - public MountpointStateVESMessageFormatter(VESCollectorCfgService vesCfg) { + public MountpointStateVESMessageFormatter(VESCollectorCfgService vesCfg, VESCollectorService vesCollectorService) { this.vesCfg = vesCfg; + this.vesCollectorService = vesCollectorService; } private static void incrSequenceNo() { @@ -47,26 +53,22 @@ public class MountpointStateVESMessageFormatter { return sequenceNo; } - public String createVESMessage(JSONObject obj) { + public VESMessage createVESMessage(JSONObject obj) { if (LOG.isDebugEnabled()) { LOG.debug("JSON Object to format to VES is - {0}", obj); } - String vesMsg = "{}"; + MountpointStateVESMessageFormatter.incrSequenceNo(); VESCommonEventHeaderPOJO vesCommonEventHeader = createVESCommonEventHeader(obj); VESNotificationFieldsPOJO vesNotificationFields = createVESNotificationFields(obj); - VESEvent vesEvent = new VESEvent(); - vesEvent.addEventObjects(vesCommonEventHeader); - vesEvent.addEventObjects(vesNotificationFields); - + VESMessage vesMsg = null; try { - ObjectMapper objMapper = new ObjectMapper(); - vesMsg = objMapper.writeValueAsString(vesEvent); - LOG.debug("VES message to be published - {}", vesMsg); + vesMsg = vesCollectorService.generateVESEvent(vesCommonEventHeader, vesNotificationFields); + LOG.info("VES Message is - {}", vesMsg.getMessage()); } catch (JsonProcessingException e) { - LOG.warn("Exception {} while processing JSON Message - {}", e, obj); + LOG.error("Exception while generating VES Event - ", e); } return vesMsg; diff --git a/sdnr/wt/mountpoint-state-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/test/TestMountpointStatePublisher.java b/sdnr/wt/mountpoint-state-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/test/TestMountpointStatePublisher.java index 468e0c1ee..ebf4cb894 100644 --- a/sdnr/wt/mountpoint-state-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/test/TestMountpointStatePublisher.java +++ b/sdnr/wt/mountpoint-state-provider/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/mountpointstateprovider/test/TestMountpointStatePublisher.java @@ -34,6 +34,7 @@ import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.DeviceManagerServic import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.NetconfNetworkElementService; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorCfgService; import org.onap.ccsdk.features.sdnr.wt.devicemanager.service.VESCollectorService; +import org.onap.ccsdk.features.sdnr.wt.devicemanager.types.VESMessage; import org.onap.ccsdk.features.sdnr.wt.mountpointstateprovider.impl.MountpointStatePublisher; public class TestMountpointStatePublisher { @@ -41,7 +42,7 @@ public class TestMountpointStatePublisher { MountpointStatePublisher mountpointStatePublisher; VESCollectorService vesCollectorService; VESCollectorCfgService vesCfg; - String vesMsg = "{}"; + VESMessage vesMsg; JSONObject testJsonData; @Before @@ -64,7 +65,7 @@ public class TestMountpointStatePublisher { mountpointStatePublisher = new MountpointStatePublisher(vesCollectorService); mountpointStatePublisher.addToPublish(testJsonData); - //mountpointStatePublisher.getStateObjects().add(testJsonData); + mountpointStatePublisher.getStateObjects().add(testJsonData); } @Test diff --git a/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfAccessor.java b/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfAccessor.java index f24503957..fa544e19a 100644 --- a/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfAccessor.java +++ b/sdnr/wt/netconfnode-state-service/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/NetconfAccessor.java @@ -18,6 +18,7 @@ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice; import java.util.Optional; +import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; @@ -29,6 +30,11 @@ public interface NetconfAccessor { static String DefaultNotificationsStream = "NETCONF"; /** + * @return the Controller DataBroker + */ + DataBroker getControllerBindingDataBroker(); + + /** * @return the nodeId */ NodeId getNodeId(); diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java index 92ce34b16..d3752cdc4 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/NetconfNodeStateServiceImpl.java @@ -221,7 +221,7 @@ public class NetconfNodeStateServiceImpl LOG.info("Session Initiated start {}", APPLICATION_NAME); this.domContext = new DomContext(this.yangParserFactory, this.bindingNormalizedNodeSerializer); this.netconfCommunicatorManager = new NetconfCommunicatorManager(mountPointService, domMountPointService, domContext); - this.accessorManager = new NetconfAccessorManager(netconfCommunicatorManager, domContext); + this.accessorManager = new NetconfAccessorManager(netconfCommunicatorManager, domContext, this); // Start RPC Service this.rpcApiService = new NetconfnodeStateServiceRpcApiImpl(rpcProviderRegistry, vesNotificationListenerList); // Get configuration @@ -266,6 +266,10 @@ public class NetconfNodeStateServiceImpl return Objects.requireNonNull(domContext, "Initialization not completed for domContext" ); } + public DataBroker getDataBroker() { + return dataBroker; + } + public NetconfnodeStateServiceRpcApiImpl getNetconfnodeStateServiceRpcApiImpl() { return Objects.requireNonNull(rpcApiService, "Initialization not completed for rpcApiService" ); } diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorImpl.java index 189845831..8eba4e7ef 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorImpl.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorImpl.java @@ -23,7 +23,9 @@ import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.Capabilities; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfBindingAccessor; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfDomAccessor; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.dom.DomContext; +import org.opendaylight.mdsal.binding.api.DataBroker; 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.ConnectionStatus; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; @@ -40,7 +42,7 @@ public class NetconfAccessorImpl implements NetconfAccessor { private final Capabilities capabilities; private final NetconfCommunicatorManager netconfCommunicatorManager; private final DomContext domContext; - + private final NetconfNodeStateServiceImpl netconfNodeStateService; /** * Contains all data to access and manage netconf device * @@ -52,13 +54,14 @@ public class NetconfAccessorImpl implements NetconfAccessor { * @param dataBroker to access node * @param mountpoint of netconfNode */ - public NetconfAccessorImpl(NodeId nodeId, NetconfNode netconfNode, - NetconfCommunicatorManager netconfCommunicatorManager, DomContext domContext) { + public NetconfAccessorImpl(NodeId nodeId, NetconfNode netconfNode, + NetconfCommunicatorManager netconfCommunicatorManager, DomContext domContext, NetconfNodeStateServiceImpl netconfNodeStateService) { super(); this.nodeId = Objects.requireNonNull(nodeId); this.netconfNode = Objects.requireNonNull(netconfNode); this.netconfCommunicatorManager = Objects.requireNonNull(netconfCommunicatorManager); this.domContext = Objects.requireNonNull(domContext); + this.netconfNodeStateService = Objects.requireNonNull(netconfNodeStateService); ConnectionStatus csts = netconfNode != null ? netconfNode.getConnectionStatus() : null; if (csts == null) { @@ -71,21 +74,13 @@ public class NetconfAccessorImpl implements NetconfAccessor { this.capabilities = tmp; } - /** - * @param nodeId with uuid of managed netconf node - * @param dataBroker to access node - */ - public NetconfAccessorImpl(String nodeId, NetconfNode netconfNode, - NetconfCommunicatorManager netconfCommunicatorManager, DomContext domContext) { - this(new NodeId(nodeId), netconfNode, netconfCommunicatorManager, domContext); - } - public NetconfAccessorImpl(NetconfAccessorImpl accessor) { this.nodeId = accessor.getNodeId(); this.netconfNode = accessor.getNetconfNode(); this.capabilities = accessor.getCapabilites(); this.netconfCommunicatorManager = accessor.netconfCommunicatorManager; this.domContext = accessor.domContext; + this.netconfNodeStateService = accessor.netconfNodeStateService; } @Override @@ -113,4 +108,9 @@ public class NetconfAccessorImpl implements NetconfAccessor { return netconfCommunicatorManager.getNetconfDomAccessor(this); } + @Override + public DataBroker getControllerBindingDataBroker() { + return netconfNodeStateService.getDataBroker(); + } + } diff --git a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorManager.java b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorManager.java index 280193402..6c3704421 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorManager.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/impl/access/NetconfAccessorManager.java @@ -45,15 +45,17 @@ public class NetconfAccessorManager { private final ConcurrentHashMap<NodeId, NetconfAccessor> accessorList; private final NetconfCommunicatorManager netconfCommunicatorManager; private final DomContext domContext; + private final NetconfNodeStateServiceImpl netconfNodeStateService; - public NetconfAccessorManager(NetconfCommunicatorManager netconfCommunicatorManager, DomContext domContext) { + public NetconfAccessorManager(NetconfCommunicatorManager netconfCommunicatorManager, DomContext domContext, NetconfNodeStateServiceImpl netconfNodeStateService) { this.netconfCommunicatorManager = Objects.requireNonNull(netconfCommunicatorManager); this.domContext = Objects.requireNonNull(domContext); this.accessorList = new ConcurrentHashMap<>(); + this.netconfNodeStateService = Objects.requireNonNull(netconfNodeStateService); } public NetconfAccessor getAccessor(NodeId nNodeId, NetconfNode netconfNode) { - NetconfAccessor res = new NetconfAccessorImpl(nNodeId, netconfNode, netconfCommunicatorManager, domContext); + NetconfAccessor res = new NetconfAccessorImpl(nNodeId, netconfNode, netconfCommunicatorManager, domContext, netconfNodeStateService); NetconfAccessor previouse = accessorList.put(nNodeId, res); if (Objects.nonNull(previouse)) { LOG.warn("Accessor with name already available. Replaced with new one."); diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfAccessorImpl.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfAccessorImpl.java index 1ec9cde2c..dd61db0d1 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfAccessorImpl.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/TestNetconfAccessorImpl.java @@ -23,37 +23,28 @@ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test; import static org.junit.Assert.assertEquals; import java.util.Arrays; -import java.util.Collection; import java.util.Optional; import org.junit.Assert; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNotifications; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.NetconfAccessorImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.NetconfCommunicatorManager; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.binding.NetconfBindingNotificationsImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.dom.DomContext; -import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.dom.NetconfDomAccessorImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.example.TestNetconfHelper; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.MountPoint; import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry; -import org.opendaylight.mdsal.dom.api.DOMDataBroker; -import org.opendaylight.mdsal.dom.api.DOMMountPoint; -import org.opendaylight.mdsal.dom.api.DOMNotificationListener; -import org.opendaylight.mdsal.dom.api.DOMNotificationService; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.NotificationsService; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; public class TestNetconfAccessorImpl extends Mockito { @@ -67,8 +58,9 @@ public class TestNetconfAccessorImpl extends Mockito { NetconfNode testNode = TestNetconfHelper.getTestNode(nodeId, capabilityStringForNetworkElement) .augmentation(NetconfNode.class); - NetconfAccessorImpl netconfAccessor = - new NetconfAccessorImpl(nodeId, testNode, netconfCommunicatorManager, domContext); + NetconfNodeStateServiceImpl netconfNodeStateService = mock(NetconfNodeStateServiceImpl.class); + NetconfAccessorImpl netconfAccessor = new NetconfAccessorImpl(nodeId, testNode, netconfCommunicatorManager, + domContext, netconfNodeStateService); Assert.assertNotNull(netconfAccessor); @@ -138,39 +130,4 @@ public class TestNetconfAccessorImpl extends Mockito { } - @Test - public void testNetconfDomNotification() { - - NetconfAccessorImpl netconfAccessor = TestNetconfHelper.getNetconfAcessorImpl(); - DOMDataBroker domDataBroker = mock(DOMDataBroker.class); - DOMMountPoint domMountPoint = mock(DOMMountPoint.class); - DOMNotificationService domNotificationService = mock(DOMNotificationService.class); - - YangInstanceIdentifier mountpointPath = YangInstanceIdentifier.builder() - .node(NetworkTopology.QNAME) - .build(); - when(domMountPoint.getIdentifier()).thenReturn(mountpointPath); - when(domMountPoint.getService(DOMNotificationService.class)).thenReturn(Optional.of(domNotificationService)); - - DomContext domContext = mock(DomContext.class); - - NetconfDomAccessorImpl netconfDomAccessor = - new NetconfDomAccessorImpl(netconfAccessor, domDataBroker, domMountPoint, domContext); - - Collection<SchemaPath> types = Arrays.asList(SchemaPath.create(false, NetworkTopology.QNAME)); - - DOMNotificationListener listener = (notification) -> System.out.println("Notification: "+notification); - ListenerRegistration<DOMNotificationListener> res = - netconfDomAccessor.doRegisterNotificationListener(listener, types); - - //Capture parameters and assert them - ArgumentCaptor<DOMNotificationListener> captor1 = ArgumentCaptor.forClass(DOMNotificationListener.class); - @SuppressWarnings("unchecked") - ArgumentCaptor<Collection<SchemaPath>> captor2 = ArgumentCaptor.forClass(Collection.class); - verify(domNotificationService).registerNotificationListener(captor1.capture(), captor2.capture()); - - assertEquals("Listener", listener, captor1.getValue()); - assertEquals("SchemaPath", types, captor2.getValue()); - } - } diff --git a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/example/TestNetconfHelper.java b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/example/TestNetconfHelper.java index ac466579f..2b6c77ce0 100644 --- a/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/example/TestNetconfHelper.java +++ b/sdnr/wt/netconfnode-state-service/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/netconfnodestateservice/test/example/TestNetconfHelper.java @@ -23,6 +23,7 @@ package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.example; import java.util.Arrays; import org.mockito.Mockito; +import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.NetconfAccessorImpl; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.NetconfCommunicatorManager; import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.dom.DomContext; @@ -71,8 +72,9 @@ public class TestNetconfHelper extends Mockito { NetconfNode testNode = TestNetconfHelper.getTestNode(nodeId, capabilityStringForNetworkElement) .augmentation(NetconfNode.class); + NetconfNodeStateServiceImpl netconfNodeStateService = mock(NetconfNodeStateServiceImpl.class); NetconfAccessorImpl netconfAccessor = - new NetconfAccessorImpl(nodeId, testNode, netconfCommunicatorManager, domContext); + new NetconfAccessorImpl(nodeId, testNode, netconfCommunicatorManager, domContext, netconfNodeStateService); return netconfAccessor; } } diff --git a/sdnr/wt/oauth-provider/provider-jar/pom.xml b/sdnr/wt/oauth-provider/provider-jar/pom.xml index 1b6cd8af1..5d9cbee67 100644 --- a/sdnr/wt/oauth-provider/provider-jar/pom.xml +++ b/sdnr/wt/oauth-provider/provider-jar/pom.xml @@ -186,7 +186,7 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>sdnr-wt-data-provider-provider</artifactId> + <artifactId>sdnr-wt-yang-utils</artifactId> <version>${project.version}</version> <scope>test</scope> </dependency> diff --git a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java index cd4239081..9a9f4fc04 100644 --- a/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java +++ b/sdnr/wt/oauth-provider/provider-jar/src/main/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/http/AuthHttpServlet.java @@ -37,7 +37,11 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.ShiroException; import org.apache.shiro.codec.Base64; +import org.apache.shiro.session.Session; +import org.apache.shiro.subject.Subject; import org.jolokia.osgi.security.Authenticator; import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient; import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config; @@ -66,7 +70,7 @@ public class AuthHttpServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final String BASEURI = "/oauth"; private static final String LOGINURI = BASEURI + "/login"; - //private static final String LOGOUTURI = BASEURI + "/logout"; + private static final String LOGOUTURI = BASEURI + "/logout"; private static final String PROVIDERSURI = BASEURI + "/providers"; public static final String REDIRECTURI = BASEURI + "/redirect"; private static final String REDIRECTURI_FORMAT = REDIRECTURI + "/%s"; @@ -137,6 +141,8 @@ public class AuthHttpServlet extends HttpServlet { this.sendResponse(resp, HttpServletResponse.SC_OK, getConfigs(this.providerStore.values())); } else if (req.getRequestURI().startsWith(LOGINURI)) { this.handleLoginRedirect(req, resp); + } else if (req.getRequestURI().equals(LOGOUTURI)) { + this.handleLogout(req, resp); } else if (POLICIESURI.equals(req.getRequestURI())) { this.sendResponse(resp, HttpServletResponse.SC_OK, this.getPoliciesForUser(req)); } else if (req.getRequestURI().startsWith(REDIRECTURI)) { @@ -146,7 +152,10 @@ public class AuthHttpServlet extends HttpServlet { } } - + private void handleLogout(HttpServletRequest req, HttpServletResponse resp) throws IOException { + this.logout(); + this.sendResponse(resp, HttpServletResponse.SC_OK,""); + } private void handleLoginRedirect(HttpServletRequest req, HttpServletResponse resp) throws IOException { final String uri = req.getRequestURI(); final Matcher matcher = LOGIN_REDIRECT_PATTERN.matcher(uri); @@ -458,5 +467,16 @@ public class AuthHttpServlet extends HttpServlet { os.write(output); } - + private void logout() { + final Subject subject = SecurityUtils.getSubject(); + try { + subject.logout(); + Session session = subject.getSession(false); + if (session != null) { + session.stop(); + } + } catch (ShiroException e) { + LOG.debug("Couldn't log out {}", subject, e); + } + } } diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlJsonMapper.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlJsonMapper.java index 0399655ed..7213f80f5 100644 --- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlJsonMapper.java +++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlJsonMapper.java @@ -26,8 +26,8 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions.YangToolsBuilderAnnotationIntrospector; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions.YangToolsModule; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsBuilderAnnotationIntrospector; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsModule; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.aaa.rev161214.http.permission.Permissions; import org.opendaylight.yangtools.concepts.Builder; diff --git a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlXmlMapper.java b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlXmlMapper.java index cc029bd05..b965878e8 100644 --- a/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlXmlMapper.java +++ b/sdnr/wt/oauth-provider/provider-jar/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlXmlMapper.java @@ -26,7 +26,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions.YangToolsBuilderAnnotationIntrospector; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsBuilderAnnotationIntrospector; public class OdlXmlMapper extends XmlMapper{ |