diff options
Diffstat (limited to 'ecomp-sdk/epsdk-music')
14 files changed, 1020 insertions, 24 deletions
diff --git a/ecomp-sdk/epsdk-music/pom.xml b/ecomp-sdk/epsdk-music/pom.xml index 5ef0d469..e6296c1b 100644 --- a/ecomp-sdk/epsdk-music/pom.xml +++ b/ecomp-sdk/epsdk-music/pom.xml @@ -5,12 +5,12 @@ <parent> <groupId>org.onap.portal.sdk</groupId> <artifactId>epsdk-project</artifactId> - <version>2.4.0-SNAPSHOT</version> + <version>2.5.0-SNAPSHOT</version> </parent> <groupId>org.onap.portal.sdk</groupId> <artifactId>epsdk-music</artifactId> - <version>2.4.0-SNAPSHOT</version> + <version>2.5.0-SNAPSHOT</version> <packaging>jar</packaging> <name>ONAP Portal SDK Music</name> @@ -28,7 +28,7 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <version>3.8.1</version> + <version>4.12</version> <scope>test</scope> </dependency> <dependency> @@ -125,7 +125,7 @@ <dependency> <groupId>org.onap.music</groupId> <artifactId>MUSIC</artifactId> - <version>2.5.4</version> + <version>2.5.5</version> </dependency> <!-- Mapper --> @@ -164,6 +164,13 @@ <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> + <!-- Jacoco for offline instrumentation --> + <dependency> + <groupId>org.jacoco</groupId> + <artifactId>org.jacoco.agent</artifactId> + <version>${jacoco.version}</version> + <classifier>runtime</classifier> + </dependency> </dependencies> <profiles> <!-- disable doclint, a new feature in Java 8, when generating javadoc --> diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/EnableMuscicHttpSession.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/EnableMuscicHttpSession.java index 586d04ad..f44cf3f3 100644 --- a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/EnableMuscicHttpSession.java +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/EnableMuscicHttpSession.java @@ -33,7 +33,7 @@ * * ============LICENSE_END============================================ * - *. + * */ package org.onap.portalapp.music.conf; diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandler.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandler.java index 7d2e51ff..0e8551b9 100644 --- a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandler.java +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandler.java @@ -55,40 +55,50 @@ public class MusicSessionRepositoryHandler { public Session get(String id) { - if(!musicCache){ + if(musicCache){ + // todo need to add the clean up for "sessions" map if musicCache is enabled + return this.sessions.get(id); + }else{ try { Session session = MusicService.getMetaAttribute(id); return session; } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger, "get failed with id " + id, e); + return null; } - } - return this.sessions.get(id); + } } public void remove(String id) { - sessions.remove(id); - try { - MusicService.removeSession(id); - } catch (MusicLockingException e) { - logger.error(EELFLoggerDelegate.errorLogger, "removeSession locking failed with id " + id, e); - } catch (MusicServiceException e) { - logger.error(EELFLoggerDelegate.errorLogger, "removeSession failed with id " + id, e); + if(musicCache){ + // todo need to add the clean up for "sessions" map if musicCache is enabled + sessions.remove(id); + }else{ + try { + MusicService.removeSession(id); + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger, "removeSession locking failed with id " + id, e); + } catch (MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger, "removeSession failed with id " + id, e); + } } } public void put(String id, MusicSession musicSession) { - sessions.put(id, musicSession); - try { - MusicService.setMetaAttribute(musicSession); - MusicService.cleanUpMusic(); - } catch (Exception e) { - logger.error(EELFLoggerDelegate.errorLogger, "setMetaAttribute failed with id " + id, e); + if(musicCache){ + // todo need to add the clean up for "sessions" map if musicCache is enabled + sessions.put(id, musicSession); + }else{ + try { + MusicService.setMetaAttribute(musicSession); + MusicService.cleanUpMusic(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "setMetaAttribute failed with id " + id, e); + } } } - } diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/filter/MusicSessionRepositoryFilter.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/filter/MusicSessionRepositoryFilter.java index aa9e2e3e..694e80cd 100644 --- a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/filter/MusicSessionRepositoryFilter.java +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/filter/MusicSessionRepositoryFilter.java @@ -59,7 +59,7 @@ public class MusicSessionRepositoryFilter extends DelegatingFilterProxy{ try{ if (request instanceof HttpServletRequest) { String path = ((HttpServletRequest)request).getRequestURI().substring(((HttpServletRequest) request).getContextPath().length()); - if(MusicUtil.isExcludedApi(path)) + if(MusicUtil.isExcludedApi(path) || !MusicUtil.isMusicEnable()) request.setAttribute("org.springframework.session.web.http.SessionRepositoryFilter.FILTERED", Boolean.TRUE); } }catch(Exception e){ diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestResponse.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestResponse.java index 5a3a7416..0326e8e0 100644 --- a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestResponse.java +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestResponse.java @@ -91,6 +91,7 @@ public class RestResponse<T> { return result; } + @SuppressWarnings("rawtypes") @Override public boolean equals(Object obj) { if (this == obj) diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicProperties.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicProperties.java index 802634b6..9aae9770 100644 --- a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicProperties.java +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicProperties.java @@ -44,7 +44,6 @@ import java.io.InputStream; import java.util.Properties; import org.onap.music.eelf.logging.EELFLoggerDelegate; -import org.onap.portalapp.music.service.MusicService; public class MusicProperties { @@ -99,6 +98,8 @@ public class MusicProperties { public static final String MUSIC_CLEAN_UP_THRESHOLD = "music.cleanup.threshold"; + public static final String MUSIC_ENABLE = "music.enable"; + public static final String SESSION_MAX_INACTIVE_INTERVAL_SECONDS = "music.session.max.inactive.interval.seconds"; public static final String ATTRIBUTE_NAME = "ATTRIBUTE_NAME"; diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicUtil.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicUtil.java index d7de16bd..15c3bb0c 100644 --- a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicUtil.java +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicUtil.java @@ -67,10 +67,13 @@ public class MusicUtil { private static String cached = MusicProperties.getProperty(MusicProperties.MUSIC_CACHE); private static String cleanUpFreq = MusicProperties.getProperty(MusicProperties.MUSIC_CLEAN_UP_FREQUENCY); private static String musicSerializeCompress = MusicProperties.getProperty(MusicProperties.MUSIC_SERIALIZE_COMPRESS); + private static String musicEnable = MusicProperties.getProperty(MusicProperties.MUSIC_ENABLE); + public static boolean isSessionMetaAttr(String key){ return sessionAttrNameSet.contains(key); } + @SuppressWarnings("unchecked") public static <T> T musicRestResponseDataParsing(ResultSet rs, String attributeName) throws Exception{ logger.debug(EELFLoggerDelegate.debugLogger, "musicRestResponseDataParsing: start"); Row row = rs.one(); @@ -83,6 +86,7 @@ public class MusicUtil { return null; } + @SuppressWarnings("unchecked") public static <T> T musicDeserialize (ByteBuffer byteBuf) throws Exception{ logger.debug(EELFLoggerDelegate.debugLogger, "musicDeserialize: start"); ByteArrayInputStream byteArr = new ByteArrayInputStream(byteBuf.array()); @@ -203,4 +207,13 @@ public class MusicUtil { return false; } } + + public static boolean isMusicEnable(){ + if(musicEnable==null) + return false; + if(musicEnable.equals("true")) + return true; + else + return false; + } } diff --git a/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandlerTest.java b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandlerTest.java new file mode 100644 index 00000000..b5a28af8 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandlerTest.java @@ -0,0 +1,103 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portalapp.music.conf; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.main.MusicCore; +import org.onap.portalapp.music.service.MusicService; +import org.onap.portalapp.music.util.MusicUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.session.Session; + +import com.datastax.driver.core.ResultSet; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MusicUtil.class, MusicCore.class}) +public class MusicSessionRepositoryHandlerTest { + + @Mock + private MusicService musicService; + + @Mock + ResultSet resultSet; + + @Before + public void setUp() { + PowerMockito.mockStatic(MusicUtil.class); + PowerMockito.mockStatic(MusicCore.class); + Mockito.when(MusicUtil.isCached()).thenReturn(true); + MockitoAnnotations.initMocks(this); + } + + @InjectMocks + MusicSessionRepositoryHandler musicSessionRepositoryHandler = new MusicSessionRepositoryHandler(); + + MusicSession ms = new MusicSession(); + + + @SuppressWarnings("static-access") + @Test + public void getTest() throws Exception { + Mockito.when(MusicCore.get(Matchers.any(PreparedQueryObject.class))).thenReturn(resultSet); + Mockito.when(musicService.getMetaAttribute("test_id")).thenReturn(ms); + Session session = musicSessionRepositoryHandler.get("test_id"); + assertNotNull(session); + } + + @SuppressWarnings("static-access") + @Test + public void getFailWithIdTest() throws Exception { + Mockito.when(MusicCore.get(Matchers.any(PreparedQueryObject.class))).thenReturn(resultSet); + Mockito.when((musicService).getMetaAttribute("test_id")).thenThrow(new NullPointerException()); + Session session = musicSessionRepositoryHandler.get("test_id"); + assertNull(session); + } +} diff --git a/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionRepositoryTest.java b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionRepositoryTest.java new file mode 100644 index 00000000..1f6af366 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionRepositoryTest.java @@ -0,0 +1,95 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portalapp.music.conf; + +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.portalapp.music.service.MusicService; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.session.Session; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MusicSession.class, MusicService.class, Session.class}) +public class MusicSessionRepositoryTest { + + + @Mock + MusicSessionRepositoryHandler handler; + + @Mock + Session session; + + @InjectMocks + MusicSessionRepository musicSessionRepository; + + MusicSession musSession = mock(MusicSession.class); + + @Before + public void setUp() throws Exception { + PowerMockito.mockStatic(MusicService.class); + PowerMockito.mockStatic(MusicSession.class); + PowerMockito.mockStatic(Session.class); + MockitoAnnotations.initMocks(this); + } + + @Test + public void setDefaultMaxInactiveIntervalTest() throws Exception { + PowerMockito.whenNew(MusicSessionRepositoryHandler.class).withNoArguments().thenReturn(handler); + musicSessionRepository.setDefaultMaxInactiveInterval(10); + } + + @Test + public void findByIdTest() { + assertNull(musicSessionRepository.findById("1")); + } + + @Test + public void deleteByIdTest() { + musicSessionRepository.deleteById("1"); + } + +} diff --git a/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionTest.java b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionTest.java new file mode 100644 index 00000000..65290d48 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/conf/MusicSessionTest.java @@ -0,0 +1,262 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portalapp.music.conf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.time.Duration; +import java.time.Instant; +import java.util.Set; +import java.util.TreeSet; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.ReturnType; +import org.onap.portalapp.music.service.MusicService; +import org.onap.portalapp.music.util.MusicProperties; +import org.onap.portalapp.music.util.MusicUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.session.Session; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ MusicUtil.class, MusicProperties.class, MusicService.class }) +public class MusicSessionTest { + + @InjectMocks + MusicSession musicSession = new MusicSession(); + + @Mock + Session session; + + Duration duration = Duration.ofSeconds(100); + + @Before + public void setUp() { + PowerMockito.mockStatic(MusicUtil.class); + PowerMockito.mockStatic(MusicProperties.class); + PowerMockito.mockStatic(MusicService.class); + Mockito.when(MusicUtil.isCached()).thenReturn(true); + MockitoAnnotations.initMocks(this); + } + + @Mock + ReturnType rt; + + @Test + public void setLastAccessedTimeTest() { + Instant instant = Instant.now(); + musicSession.setLastAccessedTime(instant); + } + + @Test + public void setLastAccessedTimeNullPointerExceptionTest() throws Exception { + Instant instant = Instant.now(); + Mockito.when(MusicService.setAttribute(Matchers.anyString(), Matchers.any(Instant.class), Matchers.anyString())) + .thenThrow(new NullPointerException()); + musicSession.setLastAccessedTime(instant); + } + + @Test + public void musicSession() { + Set<String> values = new TreeSet<>(); + values.add("testAttName"); + values.add("testAttName2"); + Mockito.when(session.getId()).thenReturn("testId"); + Mockito.when(session.getAttributeNames()).thenReturn(values); + Mockito.when(session.getAttribute("testAttName")).thenReturn("testAttName"); + Mockito.when(session.getAttribute("testAttName2")).thenReturn("testAttName2"); + MusicSession musSession = new MusicSession(session); + assertNotNull(musSession); + } + + @Test + public void getCreationTimeTest() throws Exception { + Instant instant = Instant.now(); + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())) + .thenReturn(String.valueOf(instant)); + assertNotNull(musicSession.getCreationTime()); + } + + @Test + public void getCreationTimeInstantNowTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())).thenReturn(null); + assertNotNull(musicSession.getCreationTime()); + } + + @Test + public void getCreationTimeNullPointerExceptionTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())) + .thenThrow(new NullPointerException()); + assertNull(musicSession.getCreationTime()); + } + + @Test + public void getLastAccessedTimeTest() throws Exception { + Instant instant = Instant.now(); + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())) + .thenReturn(String.valueOf(instant)); + assertNotNull(musicSession.getCreationTime()); + } + + @Test + public void getLastAccessedTimeInstantNowTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())).thenReturn(null); + assertNotNull(musicSession.getCreationTime()); + } + + @Test + public void getLastAccessedTimeNullPointerExceptionTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())) + .thenThrow(new NullPointerException()); + assertNull(musicSession.getCreationTime()); + } + + @Test + public void setMaxInactiveIntervalTest() throws Exception { + Mockito.when(MusicService.setAttribute(Matchers.anyString(), Matchers.anyString(), Matchers.anyString())) + .thenReturn(rt); + musicSession.setMaxInactiveInterval(duration); + } + + @Test + public void setMaxInactiveIntervalNullPointerExceptionTest() throws Exception { + Mockito.when(MusicService.setAttribute(Matchers.anyString(), Matchers.anyString(), Matchers.anyString())) + .thenThrow(new NullPointerException()); + musicSession.setMaxInactiveInterval(duration); + } + + @Test + public void getMaxInactiveIntervalTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())) + .thenReturn(String.valueOf(duration)); + assertNotNull(musicSession.getMaxInactiveInterval()); + } + + @Test + public void getMaxInactiveIntervalDefaultDurationIntervalTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())).thenReturn(null); + assertNotNull(musicSession.getMaxInactiveInterval()); + } + + @Test + public void isExpiredFalseTest() throws Exception { + assertFalse(musicSession.isExpired()); + + } + + @Test + public void getAttributeTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())).thenReturn("test"); + assertNotNull(musicSession.getAttribute("test")); + } + + @Test + public void getAttributeNullPointerExceptionTest() throws Exception { + Mockito.when(MusicService.getAttribute(Matchers.anyString(), Matchers.anyString())) + .thenThrow(new NullPointerException()); + assertNull(musicSession.getAttribute("test")); + } + + @Test + public void getAttributeNamesTest() { + Set<String> sessionAttrsDummy = new TreeSet<>(); + assertEquals(sessionAttrsDummy, musicSession.getAttributeNames()); + } + + @Test + public void setAttributeTest() throws Exception { + Mockito.when(MusicService.setAttribute(Matchers.anyString(), Matchers.any(Object.class), Matchers.anyString())) + .thenReturn(rt); + musicSession.setAttribute("test_attr_name", "test_attr_value"); + } + + @Test + public void setAttributeExceptionTest() throws Exception { + Mockito.when(MusicService.setAttribute(Matchers.anyString(), Matchers.any(Object.class), Matchers.anyString())) + .thenThrow(new NullPointerException()); + musicSession.setAttribute("test_attr_name", "test_attr_value"); + } + + @Test + public void setAttributeValueNullTest() throws Exception { + Mockito.when(MusicService.setAttribute(Matchers.anyString(), Matchers.any(Object.class), Matchers.anyString())) + .thenReturn(rt); + musicSession.setAttribute("test_attr_name", null); + } + + @Test + public void removeAttributeMusicServiceExceptionTest() throws MusicServiceException, MusicLockingException { + Mockito.when(MusicService.removeAttribute(Matchers.anyString(), Matchers.anyString())) + .thenThrow(new MusicServiceException()); + musicSession.removeAttribute("test_attr_name"); + } + + @Test + public void removeAttributeMusicLockingExceptionTest() throws MusicServiceException, MusicLockingException { + Mockito.when(MusicService.removeAttribute(Matchers.anyString(), Matchers.anyString())) + .thenThrow(new MusicLockingException()); + musicSession.removeAttribute("test_attr_name"); + } + + @Test + public void setCreationTime() { + Instant instant = Instant.now(); + musicSession.setCreationTime(instant); + } + + @Test + public void setCreationExceptionTime() throws Exception { + Instant instant = Instant.now(); + Mockito.when(MusicService.setAttribute(Matchers.anyString(), Matchers.any(Instant.class), Matchers.anyString())) + .thenThrow(new MusicLockingException()); + musicSession.setCreationTime(instant); + } +} diff --git a/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/model/RestResponseTest.java b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/model/RestResponseTest.java new file mode 100644 index 00000000..2f2dfaaa --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/model/RestResponseTest.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START========================================== + * ONAP + * =================================================================== + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portalapp.music.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class RestResponseTest { + + @Test + public void restResponseTest() { + RestResponse<String> expected = new RestResponse<>(); + expected.setMessage("testMessage"); + expected.setResponse("testResponse"); + expected.setStatus(RestStatusEnum.ERROR); + RestResponse<String> actual = new RestResponse<String>(RestStatusEnum.ERROR, "testMessage", "testResponse"); + assertEquals(expected, actual); + assertEquals(expected.hashCode(), actual.hashCode()); + assertTrue(actual.equals(expected)); + } +} diff --git a/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/service/MusicServiceTest.java b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/service/MusicServiceTest.java new file mode 100644 index 00000000..b5479371 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/service/MusicServiceTest.java @@ -0,0 +1,248 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portalapp.music.service; + +import java.nio.ByteBuffer; +import java.time.Duration; +import java.time.Instant; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.MusicCore; +import org.onap.music.main.ReturnType; +import org.onap.portalapp.music.util.MusicProperties; +import org.onap.portalapp.music.util.MusicUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.session.Session; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.client.RestTemplate; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MusicUtil.class, MusicCore.class, MusicProperties.class}) +public class MusicServiceTest { + @Mock + ReturnType returnType; + @Mock + ResultSet resultSet; + @Mock + RestTemplate restTemplate; + @Mock + Session session; + @Mock + Row row; + + @SuppressWarnings("unchecked") + @Before + public void setUp() throws MusicLockingException, MusicServiceException { + PowerMockito.mockStatic(MusicUtil.class); + PowerMockito.mockStatic(MusicCore.class); + Mockito.when(returnType.getMessage()).thenReturn("test"); + Mockito.when(row.getString(Mockito.anyString())).thenReturn("test"); + Mockito.when(resultSet.one()).thenReturn(row); + Mockito.when(MusicCore.atomicPut(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any(PreparedQueryObject.class), Mockito.any(MusicCore.Condition.class))).thenReturn(returnType); + Mockito.when(MusicCore.eventualPut(Mockito.any(PreparedQueryObject.class))).thenReturn(returnType); + Mockito.when(MusicCore.atomicGet(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.any(PreparedQueryObject.class))).thenReturn(resultSet); + Mockito.when(MusicCore.get(Mockito.any(PreparedQueryObject.class))).thenReturn(resultSet); + Mockito.when(session.getAttribute(Mockito.anyString())).thenReturn("test"); + ResponseEntity<String> entityResponse = Mockito.mock(ResponseEntity.class); + Mockito.when(entityResponse.getBody()).thenReturn("Success"); + Mockito.when(restTemplate.exchange(Mockito.any(String.class), Mockito.any(HttpMethod.class), Mockito.any(HttpEntity.class), Mockito.eq(String.class))).thenReturn(entityResponse); + Mockito.when(session.getCreationTime()).thenReturn(Instant.EPOCH); + Mockito.when(session.getLastAccessedTime()).thenReturn(Instant.EPOCH); + Mockito.when(session.getMaxInactiveInterval()).thenReturn(Duration.ZERO); + Mockito.when(MusicUtil.cleanUp()).thenReturn(true); + } + + @Test + public void testSetAttribute_WhenIsMetaIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", true); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(true); + MusicService.setAttribute("test", "test", "1"); + } + + @Test + public void testSetAttribute_WhenIsMetaIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", false); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(false); + ByteBuffer bb = Mockito.mock(ByteBuffer.class); + Mockito.when(MusicUtil.musicSerialize(Mockito.anyObject())).thenReturn(bb); + MusicService.setAttribute("test", "test", "1"); + } + + @Test + public void testSetMetaAttribute_WhenIsAutomicPutIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", true); + MusicService.setMetaAttribute(session); + } + + @Test + public void testSetMetaAttribute_WhenIsAutomicPutIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", false); + + MusicService.setMetaAttribute(session); + } + + @Test + public void testGetMetaAttribute_WhenIsAutomicPutIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicGet", true); + MusicService.getMetaAttribute("test"); + } + + @Test + public void testGetMetaAttribute_WhenIsAutomicPutIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicGet", false); + MusicService.getMetaAttribute("test"); + } + + @Test + public void testGetAttribute_WhenIsAutomicPutIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicGet", true); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(true); + MusicService.getAttribute("test", "1"); + } + + @Test + public void testGetAttribute_WhenIsAutomicPutIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicGet", false); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(false); + MusicService.getAttribute("test", "1"); + } + + @Test + public void testRemoveAttribute_WhenIsMetaIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", true); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(true); + MusicService.removeAttribute("test", "1"); + } + + @Test + public void testRemoveAttribute_WhenIsMetaIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", false); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(false); + ByteBuffer bb = Mockito.mock(ByteBuffer.class); + Mockito.when(MusicUtil.musicSerialize(Mockito.anyObject())).thenReturn(bb); + MusicService.removeAttribute("test", "1"); + } + + @Test + public void testRemoveSession_WhenIsMetaIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", true); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(true); + MusicService.removeSession("1"); + } + + @Test + public void testRemoveSession_WhenIsMetaIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", false); + Mockito.when(MusicUtil.isSessionMetaAttr(Mockito.anyString())).thenReturn(false); + ByteBuffer bb = Mockito.mock(ByteBuffer.class); + Mockito.when(MusicUtil.musicSerialize(Mockito.anyObject())).thenReturn(bb); + MusicService.removeSession("1"); + } + + @Test + public void testSetAttributeAPI_WhenIsMetaIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "template", restTemplate); + MusicService.setAttributeAPI("test", "test", session, "test", "test", true); + } + + @Test + public void testSetAttributeAPI_WhenIsMetaIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "template", null); + MusicService.setAttributeAPI("test", "test", session, "test", "test", false); + } + + @Test + public void testGetAttributeAPI_WhenIsMetaIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "template", restTemplate); + MusicService.getAttributeAPI("test", session, "test", true); + } + + @Test + public void testGetAttributeAPI_WhenIsMetaIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "template", null); + MusicService.getAttributeAPI("test", session, "test", false); + } + + @Test + public void testRemoveAttributeAPI_WhenIsMetaIsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "template", restTemplate); + MusicService.removeAttributeAPI("test", "1", true); + } + + @Test + public void testRemoveAttributeAPI_WhenIsMetaIsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "template", null); + MusicService.removeAttributeAPI("test", "1", false); + } + + @Test + public void testcleanUpMusic_WhenIsAutomicFlagsTrue() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", true); + ReflectionTestUtils.setField(MusicService.class, "isAtomicGet", true); + Mockito.when(resultSet.one()).thenReturn(null); + PowerMockito.mockStatic(MusicProperties.class); + Mockito.when(MusicProperties.getProperty("music.cleanup.threshold")).thenReturn("0"); + MusicService.cleanUpMusic(); + } + + @Test + public void testcleanUpMusic_WhenIsAutomicFlagsFalse() throws Exception { + ReflectionTestUtils.setField(MusicService.class, "isAtomicPut", false); + ReflectionTestUtils.setField(MusicService.class, "isAtomicGet", false); + Mockito.when(resultSet.one()).thenReturn(null); + PowerMockito.mockStatic(MusicProperties.class); + Mockito.when(MusicProperties.getProperty("music.cleanup.threshold")).thenReturn("0"); + MusicService.cleanUpMusic(); + } + +} diff --git a/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/util/MusicPropertiesTest.java b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/util/MusicPropertiesTest.java new file mode 100644 index 00000000..27f7ed6c --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/util/MusicPropertiesTest.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portalapp.music.util; + +import static org.junit.Assert.assertNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +public class MusicPropertiesTest { + + @Test + public void getPropertyTest() { + assertNull(MusicProperties.getProperty("test")); + } +} diff --git a/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/util/MusicUtilTest.java b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/util/MusicUtilTest.java new file mode 100644 index 00000000..008dcdfc --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/test/java/org/onap/portalapp/music/util/MusicUtilTest.java @@ -0,0 +1,145 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portalapp.music.util; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.portalapp.music.conf.MusicSession; +import org.onap.portalapp.music.service.MusicService; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ MusicProperties.class, MusicSession.class, MusicService.class, MusicCleanUp.class }) +public class MusicUtilTest { + + ResultSet result = Mockito.mock(ResultSet.class); + + Row rw = Mockito.mock(Row.class); + + @Before + public void setUp() throws Exception { + MusicCleanUp musCleapUp = mock(MusicCleanUp.class); + PowerMockito.mockStatic(MusicProperties.class); + PowerMockito.mockStatic(MusicSession.class); + PowerMockito.mockStatic(MusicService.class); + PowerMockito.mockStatic(MusicCleanUp.class); + Mockito.when(MusicProperties.getProperty(MusicProperties.MUSIC_ATOMIC_PUT)).thenReturn("atomic-put"); + Mockito.when(MusicProperties.getProperty(MusicProperties.MUSIC_ATOMIC_GET)).thenReturn("atomic-get"); + Mockito.when(MusicProperties.getProperty(MusicProperties.MUSIC_CACHE)).thenReturn("cache"); + Mockito.when(MusicProperties.getProperty(MusicProperties.MUSIC_EXCLUDE_API)).thenReturn("test1,test2"); + PowerMockito.when(MusicProperties.getProperty(MusicProperties.MUSIC_SERIALIZE_COMPRESS)).thenReturn("compress"); + PowerMockito.when(MusicCleanUp.getInstance()).thenReturn(musCleapUp); + PowerMockito.when(musCleapUp.getLastCleanUpTime()).thenReturn(null); + MockitoAnnotations.initMocks(this); + } + + @Test + public void isSessionMetaAttrTest() { + assertTrue(MusicUtil.isSessionMetaAttr("CREATION_TIME")); + } + + @Test + public void musicRestResponseDataParsingTest() throws Exception { + List<Row> rows = new ArrayList<Row>(); + Mockito.doReturn("creation time").when(rw).getString("CREATION_TIME"); + rows.add(rw); + Mockito.doReturn(rows.get(0)).when(result).one(); + assertNotNull(MusicUtil.musicRestResponseDataParsing(result, "CREATION_TIME")); + } + + @Test + public void getMusicExcludedAPITest() { + assertNotNull(MusicUtil.getMusicExcludedAPI()); + } + + @Test + public void isExcludedApiTest() { + assertTrue(MusicUtil.isExcludedApi("test1")); + } + + @Test + public void isExcludedApiFalseTest() { + assertFalse(MusicUtil.isExcludedApi("test3")); + } + + @Test + public void isMusicSerializeCompressReturnFalseTest() { + assertFalse(MusicUtil.isMusicSerializeCompress()); + } + + @Test + public void isAtomicPutTest() { + assertFalse(MusicUtil.isAtomicPut()); + } + + @Test + public void isAtomicGetTest() { + assertFalse(MusicUtil.isAtomicGet()); + } + + @Test + public void isCachedTest() { + assertFalse(MusicUtil.isCached()); + } + + @Test + public void convertHoursToMillSecTest() { + assertNotNull(MusicUtil.convertHoursToMillSec(1)); + } + + @Test + public void cleanUpTest() { + assertFalse(MusicUtil.cleanUp()); + } +} |