diff options
author | 2018-03-19 17:37:22 -0400 | |
---|---|---|
committer | 2018-03-19 17:37:22 -0400 | |
commit | a932df953215fa4fe25d0dee962291eaa64d1846 (patch) | |
tree | 5106087e4723b93d6d3690ad37f560f6a7257e31 /ecomp-sdk/epsdk-music/src/main/java/org/onap | |
parent | dcdf1bb1838de59e16c63ab37b29fb913efe2f69 (diff) |
Effort to make portal resilient
Issue-ID: PORTAL-210
Includes music library that contatins session management
Change-Id: Icacab904e1f948068348fcc19cd77965cb5b446e
Signed-off-by: Lo, WEI-TING(wl849v) <wl849v@att.com>
Diffstat (limited to 'ecomp-sdk/epsdk-music/src/main/java/org/onap')
11 files changed, 1796 insertions, 0 deletions
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 new file mode 100644 index 00000000..fcdb15fe --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/EnableMuscicHttpSession.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.music.conf; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +@Configuration +@Import(MusicHttpSessionConfiguration.class) +public @interface EnableMuscicHttpSession { + +} diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicHttpSessionConfiguration.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicHttpSessionConfiguration.java new file mode 100644 index 00000000..bdf952bb --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicHttpSessionConfiguration.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.music.conf; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; + +@EnableSpringHttpSession +@Configuration +public class MusicHttpSessionConfiguration { + + + @Bean + public MusicSessionRepository sessionRepository() { + return new MusicSessionRepository(new MusicSessionRepositoryHandler()); + } +} + diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSession.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSession.java new file mode 100644 index 00000000..dfaf5dc7 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSession.java @@ -0,0 +1,382 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +/* + * Copyright 2014-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.portalapp.music.conf; + +import java.io.Serializable; +import java.time.Duration; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.portalapp.music.service.MusicService; +import org.onap.portalapp.music.util.MusicProperties; +import org.onap.portalapp.music.util.MusicUtil; +import org.springframework.session.MapSession; +import org.springframework.session.Session; + +/** + * <p> + * A {@link Session} implementation that is backed by a {@link java.util.Map}. The + * defaults for the properties are: + * </p> + * <ul> + * <li>id - a secure random generated id</li> + * <li>creationTime - the moment the {@link MapSession} was instantiated</li> + * <li>lastAccessedTime - the moment the {@link MapSession} was instantiated</li> + * <li>maxInactiveInterval - 30 minutes</li> + * </ul> + * + * <p> + * This implementation has no synchronization, so it is best to use the copy constructor + * when working on multiple threads. + * </p> + * + * @author SRIDHAR REDDY M + * @since 1.0 + */ +public final class MusicSession implements Session, Serializable { + /** + * Default {@link #setMaxInactiveInterval(Duration)} (30 minutes). + */ + public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = MusicProperties.getProperty(MusicProperties.SESSION_MAX_INACTIVE_INTERVAL_SECONDS)==null ? 1800 :Integer.valueOf(MusicProperties.getProperty(MusicProperties.SESSION_MAX_INACTIVE_INTERVAL_SECONDS)) ; + private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicSession.class); + + private String id; + private String originalId; + private Map<String, Object> sessionAttrs = new HashMap<>(); + private Instant creationTime = Instant.now(); + private Instant lastAccessedTime = this.creationTime; + private Map<String,Integer> cachingMap = new HashMap<>(); + private boolean musicCache = MusicUtil.isCached(); + /** + * Defaults to 30 minutes. + */ + private Duration maxInactiveInterval = Duration.ofSeconds(DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS); + + /** + * Creates a new instance with a secure randomly generated identifier. + */ + public MusicSession() { + this(generateId()); + } + + + /** + * Creates a new instance with the specified id. This is preferred to the default + * constructor when the id is known to prevent unnecessary consumption on entropy + * which can be slow. + * + * @param id the identifier to use + */ + public MusicSession(String id) { + this.id = id; + this.originalId = id; + } + + /** + * Creates a new instance from the provided {@link Session}. + * + * @param session the {@link Session} to initialize this {@link Session} with. Cannot + * be null. + */ + public MusicSession(Session session) { + if (session == null) { + throw new IllegalArgumentException("session cannot be null"); + } + this.id = session.getId(); + this.originalId = this.id; + this.sessionAttrs = new HashMap<>( + session.getAttributeNames().size()); + for (String attrName : session.getAttributeNames()) { + Object attrValue = session.getAttribute(attrName); + if (attrValue != null) { + this.sessionAttrs.put(attrName, attrValue); + } + } + this.creationTime = session.getCreationTime(); + this.lastAccessedTime = session.getLastAccessedTime(); + this.maxInactiveInterval = session.getMaxInactiveInterval(); + } + + @Override + public void setLastAccessedTime(Instant lastAccessedTime) { + logger.debug(EELFLoggerDelegate.debugLogger, "setLastAccessedTime: start"); + try{ + MusicService.setAttribute(MusicProperties.LAST_ACCESS_TIME, this.lastAccessedTime, this.id); + }catch(Exception e){ + logger.error(EELFLoggerDelegate.errorLogger, "setLastAccessedTime failed with id " + this.id, e); + } + this.lastAccessedTime = lastAccessedTime; + } + + @Override + public Instant getCreationTime() { + Instant creationTime = null; + logger.debug(EELFLoggerDelegate.debugLogger, "getCreationTime: start"); + if(musicCache) + creationTime = this.creationTime; + else{ + try { + String creationTimeStr = MusicService.getAttribute( MusicProperties.CREATION_TIME, this.id); + if(creationTimeStr!=null) + creationTime = Instant.parse(creationTimeStr); + else + creationTime = Instant.now(); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "getCreationTime failed with id " + this.id, e); + } + } + return creationTime; + } + + @Override + public String getId() { + return this.id; + } + + String getOriginalId() { + return this.originalId; + } + + void setOriginalId(String originalId) { + this.originalId = originalId; + } + + @Override + public String changeSessionId() { + String changedId = generateId(); + setId(changedId); + return changedId; + } + + @Override + public Instant getLastAccessedTime() { + Instant lastAccessedTime = null; + logger.debug(EELFLoggerDelegate.debugLogger, "getLastAccessedTime: start"); + if(musicCache) + lastAccessedTime = this.lastAccessedTime; + else{ + try { + String lastAccessedTimeStr = MusicService.getAttribute( MusicProperties.LAST_ACCESS_TIME, this.id); + if(lastAccessedTimeStr!=null) + lastAccessedTime = Instant.parse(lastAccessedTimeStr); + else + lastAccessedTime = this.creationTime; + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "getLastAccessedTime failed with id "+this.id, e); + } + } + return lastAccessedTime; + } + + @Override + public void setMaxInactiveInterval(Duration interval) { + logger.debug(EELFLoggerDelegate.debugLogger, "setMaxInactiveInterval: start"); + this.maxInactiveInterval = interval; + try{ + MusicService.setAttribute(MusicProperties.MAX_INACTIVE_INTERVAL, this.maxInactiveInterval, this.id); + }catch(Exception e){ + logger.error(EELFLoggerDelegate.errorLogger, "setMaxInactiveInterval failed with id " + this.id, e); + } + } + + @Override + public Duration getMaxInactiveInterval() { + logger.debug(EELFLoggerDelegate.debugLogger, "getMaxInactiveInterval: start"); + Duration maxInactiveInterval = null; + if(musicCache) + maxInactiveInterval = this.maxInactiveInterval; + else{ + try { + String maxInactiveIntervalStr = MusicService.getAttribute( MusicProperties.MAX_INACTIVE_INTERVAL, this.id); + if(maxInactiveIntervalStr!=null) + maxInactiveInterval = Duration.parse(maxInactiveIntervalStr); + else + maxInactiveInterval = Duration.ofSeconds(DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "getMaxInactiveInterval failed with id " + this.id, e); + } + } + return maxInactiveInterval==null? Duration.ofSeconds(DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS):maxInactiveInterval; + } + + @Override + public boolean isExpired() { + return isExpired(Instant.now()); + } + + boolean isExpired(Instant now) { + logger.debug(EELFLoggerDelegate.debugLogger, "isExpired: start"); + boolean isExpired = false; + Duration maxInactiveInterval = null; + Instant lastAccessedTime = null; + try { + if(musicCache){ + maxInactiveInterval = this.maxInactiveInterval; + lastAccessedTime = this.lastAccessedTime; + }else{ + maxInactiveInterval = getMaxInactiveInterval(); + lastAccessedTime = getLastAccessedTime(); + } + if (maxInactiveInterval.isNegative()) { + return false; + } + isExpired = now.minus(maxInactiveInterval).compareTo(lastAccessedTime) >= 0; + if(isExpired){ + MusicService.removeSession(this.id); + } + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger, "isExpired locking failed with id:" + id, e); + } catch (MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger, "isExpired failed with id:" + id, e); + } + return isExpired; + } + + @Override + @SuppressWarnings("unchecked") + public <T> T getAttribute(String attributeName) { + if(musicCache){ + return (T) this.sessionAttrs.get(attributeName); + }else{ + try { + return MusicService.getAttribute( attributeName, this.id); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, " getAttribute failed with id:" + this.id + " attribute name "+ attributeName , e); + return null; + } + } + + } + + @Override + public Set<String> getAttributeNames() { + return this.sessionAttrs.keySet(); + } + + @Override + public void setAttribute(String attributeName, Object attributeValue) { + if (attributeValue == null) { + removeAttribute(attributeName); + }else { + this.sessionAttrs.put(attributeName, attributeValue); + try{ + MusicService.setAttribute(attributeName , attributeValue, this.id); + }catch(Exception e){ + logger.error(EELFLoggerDelegate.errorLogger, " setAttribute failed id:" + this.id + " attribute name "+ attributeName , e); + } + } + } + + @Override + public void removeAttribute(String attributeName) { + this.sessionAttrs.remove(attributeName); + try{ + MusicService.removeAttribute(attributeName, this.id); + }catch(MusicLockingException e){ + logger.error(EELFLoggerDelegate.errorLogger, " removeAttribute locking failed id:" + this.id + " attribute name "+ attributeName , e); + }catch(MusicServiceException e){ + logger.error(EELFLoggerDelegate.errorLogger, " removeAttribute failed id:" + this.id + " attribute name "+ attributeName , e); + } + + } + + /** + * Sets the time that this {@link Session} was created. The default is when the + * {@link Session} was instantiated. + * @param creationTime the time that this {@link Session} was created. + */ + public void setCreationTime(Instant creationTime) { + //MusicService musicService = new MusicService(); + this.creationTime = creationTime; + try{ + MusicService.setAttribute(MusicProperties.CREATION_TIME, creationTime, this.id); + }catch(Exception e){ + logger.error(EELFLoggerDelegate.errorLogger, " setCreationTime failed id:" + this.id + " creationTime "+ creationTime , e); + } + + } + + /** + * Sets the identifier for this {@link Session}. The id should be a secure random + * generated value to prevent malicious users from guessing this value. The default is + * a secure random generated identifier. + * + * @param id the identifier for this session. + */ + public void setId(String id) { + this.id = id; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Session && this.id.equals(((Session) obj).getId()); + } + + @Override + public int hashCode() { + return this.id.hashCode(); + } + + private static String generateId() { + return UUID.randomUUID().toString(); + } + + private static final long serialVersionUID = 7160779239673823561L; +} diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionConfig.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionConfig.java new file mode 100644 index 00000000..617ac75b --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionConfig.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.music.conf; + +import org.springframework.context.annotation.Configuration; + +/** + * Configures Spring features in the ONAP Portal SDK including request + * interceptors and view resolvers. Application should subclass and override + * methods as needed. + */ + + + +@Configuration +@EnableMuscicHttpSession +public class MusicSessionConfig { + +} + diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepository.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepository.java new file mode 100644 index 00000000..37a7ae7e --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepository.java @@ -0,0 +1,135 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.music.conf; + +import java.time.Duration; +import java.util.Map; + +import org.springframework.session.Session; +import org.springframework.session.SessionRepository; +import org.springframework.session.events.SessionDeletedEvent; +import org.springframework.session.events.SessionExpiredEvent; + + +/** + * A {@link SessionRepository} backed by a {@link java.util.Map} and that uses a + * {@link MapSession}. The injected {@link java.util.Map} can be backed by a + * distributed NoSQL store like Hazelcast, for instance. Note that the supplied + * map itself is responsible for purging the expired sessions. + * + * <p> + * The implementation does NOT support firing {@link SessionDeletedEvent} or + * {@link SessionExpiredEvent}. + * </p> + * + * @author SRIDHAR REDDY M + * @since 1.0 + */ +public class MusicSessionRepository implements SessionRepository<MusicSession> { + + /** + * If non-null, this value is used to override + * {@link Session#setMaxInactiveInterval(Duration)}. + */ + private Integer defaultMaxInactiveInterval; + + + private final MusicSessionRepositoryHandler sessionHandler; + + /** + * Creates a new instance backed by the provided {@link java.util.Map}. This + * allows injecting a distributed {@link java.util.Map}. + * + * @param sessions + * the {@link java.util.Map} to use. Cannot be null. + */ + public MusicSessionRepository(MusicSessionRepositoryHandler handler) { + this.sessionHandler = handler; + } + + /** + * If non-null, this value is used to override + * {@link Session#setMaxInactiveInterval(Duration)}. + * + * @param defaultMaxInactiveInterval + * the number of seconds that the {@link Session} should be kept + * alive between client requests. + */ + public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) { + this.defaultMaxInactiveInterval = defaultMaxInactiveInterval; + } + + @Override + public void save(MusicSession session) { + if (!session.getId().equals(session.getOriginalId())) { + this.sessionHandler.remove(session.getOriginalId()); + session.setOriginalId(session.getId()); + } + // this.sessionHandler.put(session.getId(), new MusicSession(session)); + this.sessionHandler.put(session.getId(), new MusicSession(session)); + } + + @Override + public MusicSession findById(String id) { + Session saved = this.sessionHandler.get(id); + if (saved == null) { + return null; + } + if (saved.isExpired()) { + deleteById(saved.getId()); + return null; + } + //return sessionHandler.session(saved); + return new MusicSession(saved); + } + + @Override + public void deleteById(String id) { + this.sessionHandler.remove(id); + } + + @Override + public MusicSession createSession() { + MusicSession result = new MusicSession(); + if (this.defaultMaxInactiveInterval != null) { + result.setMaxInactiveInterval(Duration.ofSeconds(this.defaultMaxInactiveInterval)); + } + return result; + } + +} 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 new file mode 100644 index 00000000..1b0dff94 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/conf/MusicSessionRepositoryHandler.java @@ -0,0 +1,56 @@ +package org.onap.portalapp.music.conf; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.portalapp.music.service.MusicService; +import org.onap.portalapp.music.util.MusicUtil; +import org.springframework.session.Session; + +public class MusicSessionRepositoryHandler { + + private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicSessionRepositoryHandler.class); + private final Map<String, Session> sessions = new ConcurrentHashMap<>(); + private boolean musicCache = MusicUtil.isCached(); + + + public Session get(String id) { + if(!musicCache){ + try { + Session session = MusicService.getMetaAttribute(id); + return session; + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "get failed with id " + id, e); + } + } + 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); + } + } + + + + public void put(String id, MusicSession musicSession) { + sessions.put(id, musicSession); + try { + MusicService.setMetaAttribute(musicSession); + } 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/model/RestResponse.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestResponse.java new file mode 100644 index 00000000..d01b0105 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestResponse.java @@ -0,0 +1,119 @@ +/*- + * ============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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.music.model; + +public class RestResponse<T> { + + private RestStatusEnum status; + private String message; + + private T response; + + public RestResponse(){}; + + public RestResponse(RestStatusEnum status, String message, T response){ + this.status = status; + this.message = message; + this.response = response; + } + + public RestStatusEnum getStatus() { + return status; + } + + public void setStatus(RestStatusEnum status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getResponse() { + return response; + } + + public void setResponse(T response) { + this.response = response; + } + + @Override + public String toString() { + return "RestResponse [status=" + status + ", message=" + message + ", response=" + response + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((message == null) ? 0 : message.hashCode()); + result = prime * result + ((response == null) ? 0 : response.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RestResponse other = (RestResponse) obj; + if (message == null) { + if (other.message != null) + return false; + } else if (!message.equals(other.message)) + return false; + if (response == null) { + if (other.response != null) + return false; + } else if (!response.equals(other.response)) + return false; + if (status != other.status) + return false; + return true; + }; + + +} diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestStatusEnum.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestStatusEnum.java new file mode 100644 index 00000000..61e477c3 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/model/RestStatusEnum.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.music.model; + +public enum RestStatusEnum{ + OK("ok"), + WARN("WARNING"), + ERROR("error"); + + private String value; + private RestStatusEnum(String value){ + this.value = value; + } + + @Override + public String toString() { + return value; + } +} diff --git a/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/service/MusicService.java b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/service/MusicService.java new file mode 100644 index 00000000..0ff3cd2a --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/service/MusicService.java @@ -0,0 +1,543 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ + +package org.onap.portalapp.music.service; + +import java.util.HashMap; +import java.util.Map; + +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +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.conf.MusicSession; +import org.onap.portalapp.music.model.RestResponse; +import org.onap.portalapp.music.model.RestStatusEnum; +import org.onap.portalapp.music.util.MusicProperties; +import org.onap.portalapp.music.util.MusicUtil; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.session.Session; +import org.springframework.web.client.RestTemplate; + +import com.datastax.driver.core.ResultSet; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class MusicService { + static RestTemplate template = new RestTemplate(); + private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicService.class); + + private static boolean isAtomicPut = MusicUtil.isAtomicPut(); + private static boolean isAtomicGet = MusicUtil.isAtomicGet(); + private static String musicKeySpace = MusicProperties.getProperty(MusicProperties.MUSIC_SESSION_KEYSPACE); + private static String musicMetaTable = MusicProperties.getProperty(MusicProperties.MUSIC_SESSION_META_TABLES); + private static String musicAttrTable = MusicProperties.getProperty(MusicProperties.MUSIC_SESSION_ATTR_TABLES); + + /** + * Store session attribute name and values into Cassandra via Music + * + * @param attributeName + * @param value + * @param sessionId + * @return ReturnType that includes required body information for Music api + * @throws Exception + */ + public static ReturnType setAttribute(String attributeName, Object value, String sessionId) throws Exception { + logger.debug(EELFLoggerDelegate.debugLogger, "setAttribute: start with id " + sessionId); + String tableName = null; + ReturnType result = null; + boolean isMeta = MusicUtil.isSessionMetaAttr(attributeName); + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder querySB = new StringBuilder(); + querySB.append("INSERT INTO ").append(musicKeySpace).append(".").append(getTableName(isMeta)) + .append(getInsertQuery(isMeta, attributeName)); + + queryObject.appendQueryString(querySB.toString()); + if (isMeta) { + queryObject.addValue(sessionId); + queryObject.addValue(String.valueOf(value)); + tableName = musicMetaTable; + } else { + queryObject.addValue(sessionId); + queryObject.addValue(attributeName); + queryObject.addValue(MusicUtil.musicSerialize(value)); + tableName = musicAttrTable; + + } + if (isAtomicPut) + result = MusicCore.atomicPut(musicKeySpace, tableName, sessionId, queryObject, null); + else + result = MusicCore.eventualPut(queryObject); + logger.debug(EELFLoggerDelegate.debugLogger, "setAttribute: attributeName: " + attributeName + + " with session id: " + sessionId + "result:" + result.getMessage()); + return result; + } + + /** + * Store session meta data values into Cassandra via Music + * + * @param session + * @return ReturnType that includes required body information for Music api + * @throws Exception + */ + public static ReturnType setMetaAttribute(Session session) throws Exception { + logger.debug(EELFLoggerDelegate.debugLogger, "setMetaAttribute: start with session id: " + session.getId()); + ReturnType result = null; + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder querySB = new StringBuilder(); + querySB.append("INSERT INTO ").append(musicKeySpace).append(".").append(musicMetaTable).append("(") + .append(MusicProperties.PRIMARY_ID).append(",").append(MusicProperties.CREATION_TIME).append(",") + .append(MusicProperties.LAST_ACCESS_TIME).append(",").append(MusicProperties.MAX_INACTIVE_INTERVAL) + .append(",").append(MusicProperties.SESSION_ID).append(") VALUES (?,?,?,?,?);"); + + queryObject.appendQueryString(querySB.toString()); + queryObject.addValue(session.getId()); + queryObject.addValue(String.valueOf(session.getCreationTime())); + queryObject.addValue(String.valueOf(session.getLastAccessedTime())); + queryObject.addValue(String.valueOf(session.getMaxInactiveInterval())); + queryObject.addValue(session.getId()); + if (isAtomicPut) + result = MusicCore.atomicPut(musicKeySpace, musicMetaTable, session.getId(), queryObject, null); + else + result = MusicCore.eventualPut(queryObject); + logger.debug(EELFLoggerDelegate.debugLogger, + "setMetaAttribute: with session id: " + session + "result:" + result.getMessage()); + + return result; + } + + /** + * Retrieve session meta data from Cassandra via Music + * + * @param sessionId + * @return MusicSession + * @throws Exception + */ + public static MusicSession getMetaAttribute(String sessionId) throws Exception { + logger.debug(EELFLoggerDelegate.debugLogger, "getMetaAttribute: start with session Id: "+ sessionId); + ResultSet result = null; + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder querySB = new StringBuilder(); + querySB.append("SELECT * FROM ").append(musicKeySpace).append(".").append(musicMetaTable).append(" WHERE ") + .append(MusicProperties.PRIMARY_ID).append("=?;"); + queryObject.appendQueryString(querySB.toString()); + queryObject.addValue(sessionId); + if (isAtomicGet) + result = MusicCore.atomicGet(musicKeySpace, musicMetaTable, sessionId, queryObject); + else + result = MusicCore.get(queryObject); + logger.debug(EELFLoggerDelegate.debugLogger, "getMetaAttribute: with session id: " + sessionId); + return MusicUtil.parseMetaData(result.one()); + } + + /** + * Get proper column names (from meta or attribute table) base on isMeta + * + * @param isMeta + * @param attributeName + * @return String + */ + private static String getInsertQuery(boolean isMeta, String attributeName) { + logger.debug(EELFLoggerDelegate.debugLogger, "getInsertQuery: start inserting : " + attributeName); + StringBuilder querySB = new StringBuilder(); + if (isMeta) { + querySB.append(" (").append(MusicProperties.PRIMARY_ID).append(",").append(attributeName) + .append(") VALUES (?,?);"); + } else { + querySB.append(" (").append(MusicProperties.PRIMARY_ID).append(",").append(MusicProperties.ATTRIBUTE_NAME) + .append(",").append(MusicProperties.ATTRIBUTE_BYTES).append(") VALUES (?,?,?);"); + } + return querySB.toString(); + } + + /** + * Retrieve session attribute data from Cassandra via Music + * + * @param attributeName + * @param sessionId + * @return attribute value with T type + * @throws Exception + */ + public static <T> T getAttribute(String attributeName, String sessionId) throws Exception { + logger.debug(EELFLoggerDelegate.debugLogger, "getAttribute: start with session id: " + sessionId); + ResultSet result = null; + String tableName = null; + boolean isMeta = MusicUtil.isSessionMetaAttr(attributeName); + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder querySB = new StringBuilder(); + querySB.append("SELECT ").append(getColumn(attributeName, isMeta)).append(" FROM ").append(musicKeySpace) + .append(".").append(getTableName(isMeta)).append(" WHERE ").append(MusicProperties.PRIMARY_ID) + .append("= ?"); + + queryObject.addValue(sessionId); + if (!isMeta) { + querySB.append(" and ").append(MusicProperties.ATTRIBUTE_NAME).append("= ?"); + queryObject.addValue(attributeName); + tableName = musicAttrTable; + } else + tableName = musicMetaTable; + + queryObject.appendQueryString(querySB.toString()); + if (isAtomicGet) + result = MusicCore.atomicGet(musicKeySpace, tableName, sessionId, queryObject); + else + result = MusicCore.get(queryObject); + return MusicUtil.musicRestResponseDataParsing(result, attributeName); + + } + + /** + * Remove session attribute data from Cassandra via Music + * + * @param attributeName + * @param sessionId + * @return ReturnType + * @throws MusicServiceException + * @throws MusicLockingException + */ + public static ReturnType removeAttribute(String attributeName, String sessionId) throws MusicServiceException, MusicLockingException { + logger.debug(EELFLoggerDelegate.debugLogger, "removeAttribute: start with session id: " + sessionId); + boolean isMeta = MusicUtil.isSessionMetaAttr(attributeName); + ReturnType result = null; + String tableName = null; + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder querySB = new StringBuilder(); + querySB.append("DELETE ").append(getDelColumn(isMeta, attributeName)).append(" FROM ").append(musicKeySpace) + .append(".").append(getTableName(isMeta)).append(" WHERE ").append(MusicProperties.PRIMARY_ID) + .append("= ? "); + queryObject.addValue(sessionId); + + if (!isMeta) { + querySB.append(" and ").append(MusicProperties.ATTRIBUTE_NAME).append("= ?"); + queryObject.addValue(attributeName); + tableName = musicAttrTable; + } else + tableName = musicMetaTable; + queryObject.appendQueryString(querySB.toString()); + if (isAtomicPut) + result = MusicCore.atomicPut(musicKeySpace, tableName, sessionId, queryObject, null); + else + result = MusicCore.eventualPut(queryObject); + logger.debug(EELFLoggerDelegate.debugLogger, + "removeSession: " + attributeName + " with session id: " + sessionId + "result:" + result.getMessage()); + + return result; + } + + /** + * Remove entire session from Cassandra via Music + * + * @param sessionId + * @return ReturnType + * @throws MusicServiceException + * @throws MusicLockingException + */ + public static ReturnType removeSession(String sessionId) throws MusicServiceException, MusicLockingException { + ReturnType result = null; + boolean isAtomic = isAtomicPut; + logger.debug(EELFLoggerDelegate.debugLogger, "removeSession: start with session id: " + sessionId); + PreparedQueryObject queryObject = new PreparedQueryObject(); + StringBuilder querySB = new StringBuilder(); + querySB.append("DELETE ").append(" FROM ").append(musicKeySpace).append(".").append(musicMetaTable) + .append(" WHERE ").append(MusicProperties.PRIMARY_ID).append("= ? "); + queryObject.appendQueryString(querySB.toString()); + queryObject.addValue(sessionId); + if (isAtomic) + result = MusicCore.atomicPut(musicKeySpace, musicMetaTable, sessionId, queryObject, null); + else + result = MusicCore.eventualPut(queryObject); + logger.debug(EELFLoggerDelegate.debugLogger, "removeSession: " + musicMetaTable + " with session id: " + + sessionId + "result:" + result.getMessage()); + + queryObject = new PreparedQueryObject(); + querySB = new StringBuilder(); + querySB.append("DELETE ").append(" FROM ").append(musicKeySpace).append(".").append(musicAttrTable) + .append(" WHERE ").append(MusicProperties.PRIMARY_ID).append("= ? "); + queryObject.appendQueryString(querySB.toString()); + queryObject.addValue(sessionId); + if (isAtomic) + result = MusicCore.atomicPut(musicKeySpace, musicAttrTable, sessionId, queryObject, null); + else + result = MusicCore.eventualPut(queryObject); + + logger.debug(EELFLoggerDelegate.debugLogger, "removeSession: " + musicAttrTable + " with session id: " + + sessionId + "result:" + result.getMessage()); + + return result; + } + + /** + * Get proper table name (Meta or Attribute) base on isMeta. + * + * @param isMeta + * @return String + */ + private static String getTableName(boolean isMeta) { + StringBuilder querySB = new StringBuilder(); + if (isMeta) + querySB.append(musicMetaTable); + else + querySB.append(musicAttrTable); + return querySB.toString(); + } + + /** + * Get proper column name (Meta or Attribute) base on isMeta. + * + * @param attributeName + * @param isMeta + * @return String + */ + private static String getColumn(String attributeName, boolean isMeta) { + StringBuilder querySB = new StringBuilder(); + if (isMeta) + querySB.append(attributeName); + else + querySB.append("attribute_bytes"); + return querySB.toString(); + } + + /** + * Get proper column name (Meta or Attribute) base on isMeta for removing. + * + * @param attributeName + * @param isMeta + * @return String + */ + private static String getDelColumn(boolean isMeta, String attributeName) { + StringBuilder querySB = new StringBuilder(); + if (isMeta) + querySB.append(attributeName); + return querySB.toString(); + } + + /** + * To set session attributes in Music + * + * @param attributeName + * @param value + * @param session + * @param sessionId + * @param isMeta + * @return RestResponse<String> + * @throws JsonProcessingException + */ + + public static RestResponse<String> setAttributeAPI(String attributeName, Object value, Session session, + String sessionId, String className, boolean isMeta) throws JsonProcessingException { + System.out.println("setAttribute: " + attributeName); + RestResponse<String> portalRestResponse = null; + HttpEntity<Map<String, Object>> entity = new HttpEntity<Map<String, Object>>( + getMusicRestBody(attributeName, value, sessionId, session, className, isMeta), getMusicHeader()); + String url = getInsertUrl(isMeta); + ResponseEntity<String> response = null; + try { + response = template.exchange(url, HttpMethod.POST, entity, String.class); + portalRestResponse = new RestResponse<String>(RestStatusEnum.OK, "success", response.getBody()); + } catch (Exception e) { + portalRestResponse = new RestResponse<String>(RestStatusEnum.ERROR, e.getMessage(), null); + } + return portalRestResponse; + } + + /** + * To get session attribute in Music + * + * @param attributeName + * @param value + * @param sessionId + * @param isMeta + * @return RestResponse<String> + */ + + public static RestResponse<String> getAttributeAPI(String attributeName, Object value, String sessionId, + boolean isMeta) { + System.out.println("getAttribute: " + attributeName); + RestResponse<String> portalRestResponse = null; + HttpEntity<String> entity = new HttpEntity<String>(null, getMusicHeader()); + ResponseEntity<String> response = null; + String url = getSelectSessionIdUrl(attributeName, sessionId, isMeta); + try { + response = template.exchange(url, HttpMethod.GET, entity, String.class); + portalRestResponse = new RestResponse<String>(RestStatusEnum.OK, "success", response.getBody()); + } catch (Exception e) { + portalRestResponse = new RestResponse<String>(RestStatusEnum.ERROR, e.getMessage(), null); + } + return portalRestResponse; + } + + /** + * To remove session attribute or session meta in Music + * + * @param attributeName + * @param value + * @param sessionId + * @param isMeta + * @return RestResponse<String> + */ + public static RestResponse<String> removeAttributeAPI(String attributeName, String sessionId, boolean isMeta) { + RestResponse<String> portalRestResponse = null; + HttpEntity<Map<String, Object>> entity = new HttpEntity<>(getMusicDelRestBody(null), getMusicHeader()); + ResponseEntity<String> response = null; + String url = getSelectSessionIdUrl(attributeName, sessionId, true); + try { + response = template.exchange(url, HttpMethod.DELETE, entity, String.class); + portalRestResponse = new RestResponse<String>(RestStatusEnum.OK, "success", response.getBody()); + url = getSelectSessionIdUrl(attributeName, sessionId, false); + response = template.exchange(url, HttpMethod.DELETE, entity, String.class); + portalRestResponse = new RestResponse<String>(RestStatusEnum.OK, "success", response.getBody()); + } catch (Exception e) { + portalRestResponse = new RestResponse<String>(RestStatusEnum.ERROR, e.getMessage(), null); + } + return portalRestResponse; + } + + /** + * Generate body for Music api calls + * + * @return String that includes required body information for Music api + * calls + * @throws JsonProcessingException + */ + public static Map<String, Object> getMusicRestBody(String attributeName, Object value, String sessionId, + Session session, String className, boolean isMeta) throws JsonProcessingException { + Map<String, Object> map = new HashMap<>(); + /* Set up column values */ + Map<String, Object> valueMap = new HashMap<>(); + if (isMeta) { + valueMap.put(MusicProperties.PRIMARY_ID, session.getId()); + valueMap.put(MusicProperties.SESSION_ID, session.getId()); + valueMap.put(MusicProperties.CREATION_TIME, session.getCreationTime().toString()); + valueMap.put(MusicProperties.LAST_ACCESS_TIME, session.getLastAccessedTime().toString()); + valueMap.put(MusicProperties.MAX_INACTIVE_INTERVAL, session.getMaxInactiveInterval().toString()); + } else { + ObjectMapper mapper = new ObjectMapper(); + valueMap.put(MusicProperties.PRIMARY_ID, sessionId); + valueMap.put(MusicProperties.ATTRIBUTE_NAME, attributeName); + valueMap.put(MusicProperties.ATTRIBUTE_BYTES, mapper.writeValueAsString(value)); + valueMap.put(MusicProperties.ATTRIBUTE_CLASS, className); + } + map.put("values", valueMap); + /* Set up consistency setting */ + Map<String, String> consistencyInfoMap = new HashMap<>(); + consistencyInfoMap.put(MusicProperties.getProperty(MusicProperties.MUSIC_CONSISTENCYINFO), + MusicProperties.getProperty(MusicProperties.MUSIC_CONSISTENCYINFO_VALUE)); + map.put("consistencyInfo", consistencyInfoMap); + return map; + } + + /** + * Generate body for Music delete api calls + * + * @return String that includes required body information for Music api + * calls + * @throws JsonProcessingException + */ + public static Map<String, Object> getMusicDelRestBody(String attribute_name) { + Map<String, Object> map = new HashMap<>(); + Map<String, String> consistencyInfoMap = new HashMap<>(); + consistencyInfoMap.put(MusicProperties.getProperty(MusicProperties.MUSIC_CONSISTENCYINFO), + MusicProperties.getProperty(MusicProperties.MUSIC_CONSISTENCYINFO_VALUE)); + if (attribute_name != null && !attribute_name.equals("")) { + Map<String, String> conditionsMap = new HashMap<>(); + conditionsMap.put("attribute_name", attribute_name); + map.put("conditions", conditionsMap); + } + map.put("consistencyInfo", consistencyInfoMap); + return map; + } + + private static String getSelectSessionIdUrl(String attributeName, String sessionId, boolean isMeta) { + String path = constructPath(isMeta); + StringBuilder attriPath = new StringBuilder(); + attriPath.append(path).append(MusicProperties.getProperty(MusicProperties.MUSIC_ROWS)).append("?") + .append(MusicProperties.PRIMARY_ID).append("=").append(sessionId); + return attriPath.toString(); + } + + private static String getInsertUrl(boolean isMeta) { + String path = constructPath(isMeta); + StringBuilder attriPath = new StringBuilder(); + attriPath.append(path); + attriPath.append(MusicProperties.getProperty(MusicProperties.MUSIC_ROWS)); + return attriPath.toString(); + } + + /** + * Generate header for Music api calls + * + * @return header that contains required header information for Music api + * calls + */ + private static HttpHeaders getMusicHeader() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.add("X-minorVersion", MusicProperties.getProperty(MusicProperties.MUSIC_X_MINOR_VERSION)); + headers.add("X-patchVersion", MusicProperties.getProperty(MusicProperties.MUSIC_X_PATCH_VERSION)); + headers.add("ns", MusicProperties.getProperty(MusicProperties.MUSIC_NS)); + headers.add("userId", MusicProperties.getProperty(MusicProperties.MUSIC_USER_ID)); + headers.add("password", MusicProperties.getProperty(MusicProperties.MUSIC_PASSWORD)); + return headers; + } + + /** + * Construct URL for Music api calls + * + * @return path + */ + private static String constructPath(boolean isMeta) { + StringBuilder path = new StringBuilder(); + path.append(MusicProperties.getProperty(MusicProperties.MUSIC_ENDPOINT)) + .append(MusicProperties.getProperty(MusicProperties.MUSIC_VERSION)).append("/") + .append(MusicProperties.getProperty(MusicProperties.MUSIC_KEYSPACE)).append("/").append(musicKeySpace) + .append("/").append(MusicProperties.getProperty(MusicProperties.MUSIC_TABLES)).append("/"); + if (isMeta) + path.append(musicMetaTable); + else + path.append(musicAttrTable); + path.append("/"); + return path.toString(); + } + +} 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 new file mode 100644 index 00000000..2787b0a0 --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicProperties.java @@ -0,0 +1,217 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ + +package org.onap.portalapp.music.util; + + +import java.io.IOException; +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 { + + public static final String MUSIC_ENDPOINT = "music.endpoint"; + + public static final String MUSIC_VERSION = "music.version"; + + public static final String MUSIC_KEYSPACE = "music.keyspace"; + + public static final String MUSIC_SESSION_KEYSPACE = "music.session.keyspace"; + + public static final String MUSIC_TABLES = "TABLES"; + + public static final String MUSIC_SESSION_ATTR_TABLES = "music.session.attr.tables"; + + public static final String MUSIC_SESSION_META_TABLES = "music.session.meta.tables"; + + public static final String MUSIC_ROWS = "ROW"; + + public static final String MUSIC_SESSION_ROW = "music.sesion.rows"; + + public static final String MUSIC_X_MINOR_VERSION = "music.x.minor.version"; + + public static final String MUSIC_X_PATCH_VERSION = "music.x.patch.version"; + + public static final String MUSIC_AID = "AID"; + + public static final String MUSIC_NS = "music.ns"; + + public static final String MUSIC_USER_ID = "music.user.id"; + + public static final String MUSIC_PASSWORD = "music.password"; + + public static final String MUSIC_CONSISTENCYINFO = "music.consistency.info"; + + public static final String MUSIC_CONSISTENCYINFO_VALUE = "music.consistency.info.value"; + + public static final String MUSIC_CACHE = "music.cache"; + + public static final String MUSIC_SERIALIZE_COMPRESS = "music.serialize.compress"; + + public static final String MUSIC_ATOMIC_GET = "music.atomic.get"; + + public static final String MUSIC_ATOMIC_PUT = "music.atomic.put"; + + public static final String MUSIC_ATOMIC_POST = "music.atomic.post"; + + public static final String SESSION_MAX_INACTIVE_INTERVAL_SECONDS = "music.session.max.inactive.interval.seconds"; + + public static final String ATTRIBUTE_NAME = "ATTRIBUTE_NAME"; + + public static final String ATTRIBUTE_BYTES = "ATTRIBUTE_BYTES"; + + public static final String ATTRIBUTE_CLASS = "ATTRIBUTE_CLASS"; + + public static final String PRIMARY_ID = "PRIMARY_ID"; + + public static final String SESSION_ID = "SESSION_ID"; + + public static final String CREATION_TIME = "CREATION_TIME"; + + public static final String LAST_ACCESS_TIME = "LAST_ACCESS_TIME"; + + public static final String MAX_INACTIVE_INTERVAL = "MAX_INACTIVE_INTERVAL"; + + public static final String EXPIRY_TIME = "EXPIRY_TIME"; + + public static final String PRINCIPAL_NAME = "PRINCIPAL_NAME"; + + private MusicProperties(){} + + private static Properties properties; + + private static String propertyFileName = "music.properties"; + + private static final Object lockObject = new Object(); + + private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicProperties.class); + + /** + * Gets the property value for the specified key. If a value is found, leading + * and trailing space is trimmed. + * + * @param property + * Property key + * @return Value for the named property; null if the property file was not + * loaded or the key was not found. + */ + public static String getProperty(String property) { + if (properties == null) { + synchronized (lockObject) { + try { + if (!initialize()) { + logger.error(EELFLoggerDelegate.errorLogger, "Failed to read property file " + propertyFileName); + return null; + } + } catch (IOException e) { + logger.error(EELFLoggerDelegate.errorLogger, "Failed to read property file " + propertyFileName ,e); + return null; + } + } + } + String value = properties.getProperty(property); + if (value != null) + value = value.trim(); + return value; + } + + /** + * Reads properties from a portal.properties file on the classpath. + * + * Clients do NOT need to call this method. Clients MAY call this method to test + * whether the properties file can be loaded successfully. + * + * @return True if properties were successfully loaded, else false. + * @throws IOException + * On failure + */ + private static boolean initialize() throws IOException { + if (properties != null) + return true; + InputStream in = MusicProperties.class.getClassLoader().getResourceAsStream(propertyFileName); + if (in == null) + return false; + properties = new Properties(); + try { + properties.load(in); + } finally { + in.close(); + } + return true; + } + + /** + * Tests whether a property value is available for the specified key. + * + * @param key + * Property key + * @return True if the key is known, otherwise false. + */ +/* public static boolean containsProperty(String key) { + return environment.containsProperty(key); + }*/ + + /** + * Returns the property value associated with the given key (never + * {@code null}), after trimming any trailing space. + * + * @param key + * Property key + * @return Property value; the empty string if the environment was not + * autowired, which should never happen. + * @throws IllegalStateException + * if the key is not found + */ +/* public static String getProperty(String key) { + String value = ""; + if (environment == null) { + // logger.error(EELFLoggerDelegate.errorLogger, "getProperty: environment is null, should never happen!"); + } else { + value = environment.getRequiredProperty(key); + // java.util.Properties preserves trailing space + if (value != null) + value = value.trim(); + } + return value; + }*/ + +} 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 new file mode 100644 index 00000000..f582a9db --- /dev/null +++ b/ecomp-sdk/epsdk-music/src/main/java/org/onap/portalapp/music/util/MusicUtil.java @@ -0,0 +1,125 @@ +package org.onap.portalapp.music.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.nio.ByteBuffer; +import java.time.Duration; +import java.time.Instant; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.portalapp.music.conf.MusicSession; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; + +public class MusicUtil { + private static final Set<String> sessionAttrNameSet = new HashSet<>(Arrays.asList("CREATION_TIME", "LAST_ACCESS_TIME","MAX_INACTIVE_INTERVAL","EXPIRY_TIME","PRINCIPAL_NAME")); + + private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class); + private static String atomicPut = MusicProperties.getProperty(MusicProperties.MUSIC_ATOMIC_PUT); + private static String atomicGet = MusicProperties.getProperty(MusicProperties.MUSIC_ATOMIC_GET); + private static String cached = MusicProperties.getProperty(MusicProperties.MUSIC_CACHE); + private static String musicSerializeCompress = MusicProperties.getProperty(MusicProperties.MUSIC_SERIALIZE_COMPRESS); + public static boolean isSessionMetaAttr(String key){ + return sessionAttrNameSet.contains(key); + } + + public static <T> T musicRestResponseDataParsing(ResultSet rs, String attributeName) throws Exception{ + logger.debug(EELFLoggerDelegate.debugLogger, "musicRestResponseDataParsing: start"); + Row row = rs.one(); + if(!sessionAttrNameSet.contains(attributeName)){ + if(row!=null) + return MusicUtil.musicDeserialize(row.getBytes("attribute_bytes")); + }else{ + return (T) row.getString(attributeName); + } + return null; + } + + public static <T> T musicDeserialize (ByteBuffer byteBuf) throws Exception{ + logger.debug(EELFLoggerDelegate.debugLogger, "musicDeserialize: start"); + ByteArrayInputStream byteArr = new ByteArrayInputStream(byteBuf.array()); + ObjectInputStream ois = null; + if(isMusicSerializeCompress()){ + GZIPInputStream zos = new GZIPInputStream(byteArr); + ois = new ObjectInputStream(zos); + }else{ + ois = new ObjectInputStream(byteArr); + } + return (T) ois.readObject(); + } + + public static ByteBuffer musicSerialize (Object value) throws Exception{ + logger.debug(EELFLoggerDelegate.debugLogger, "musicSerialize: start"); + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + try { + if(isMusicSerializeCompress()){ + GZIPOutputStream zos = new GZIPOutputStream(bo); + ObjectOutputStream oos = new ObjectOutputStream(zos); + oos.writeObject(value); + oos.flush(); + zos.finish(); + }else{ + ObjectOutputStream oos = new ObjectOutputStream(bo); + oos.writeObject(value); + oos.flush(); + } + } catch (IOException e) { + logger.error(EELFLoggerDelegate.errorLogger, "Failed to serialize "); + } + return ByteBuffer.wrap(bo.toByteArray()); + } + + public static MusicSession parseMetaData (Row row) throws Exception{ + logger.debug(EELFLoggerDelegate.debugLogger, "parseMetaData: start"); + + if(row==null) + return null; + String sessionId = row.getString("primary_id"); + MusicSession musicSession = new MusicSession(sessionId); + musicSession.setCreationTime(Instant.parse(row.getString("creation_time"))); + musicSession.setLastAccessedTime(Instant.parse(row.getString("last_access_time"))); + musicSession.setMaxInactiveInterval(Duration.parse(row.getString("max_inactive_interval"))); + return musicSession; + } + + public static boolean isMusicSerializeCompress(){ + if(musicSerializeCompress==null){ + logger.error(EELFLoggerDelegate.errorLogger, "Failed to read property file " + MusicProperties.MUSIC_SERIALIZE_COMPRESS +" fall back to eventual put"); + return false; + } + return musicSerializeCompress.trim().equalsIgnoreCase("true"); + } + + public static boolean isAtomicPut(){ + if(atomicPut==null){ + logger.error(EELFLoggerDelegate.errorLogger, "Failed to read property file " + MusicProperties.MUSIC_ATOMIC_PUT +" fall back to eventual put"); + return false; + } + return atomicPut.trim().equalsIgnoreCase("true"); + } + + public static boolean isAtomicGet(){ + if(atomicGet==null){ + logger.error(EELFLoggerDelegate.errorLogger, "Failed to read property file " + MusicProperties.MUSIC_ATOMIC_GET +" fall back to eventual get"); + return false; + } + return atomicGet.trim().equalsIgnoreCase("true"); + } + + public static boolean isCached(){ + if(cached==null){ + logger.error(EELFLoggerDelegate.errorLogger, "Failed to read property file " + MusicProperties.MUSIC_CACHE +" fall back to non cache"); + return false; + } + return cached.trim().equalsIgnoreCase("true"); + } +} |