You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ya...@apache.org on 2025/11/10 23:43:06 UTC

(airavata) 16/24: update CredentialStoreServerHandler

This is an automated email from the ASF dual-hosted git repository.

yasith pushed a commit to branch resource-mgmt-rest-api
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit c1ecd12ba2b98900edfe0481109ea6cc3de79e3a
Author: yasithdev <ya...@icloud.com>
AuthorDate: Mon Nov 10 18:40:24 2025 -0500

    update CredentialStoreServerHandler
---
 .../store/server/CredentialStoreServerHandler.java | 402 ++-------------------
 .../CredentialStoreService.java}                   | 158 +++-----
 2 files changed, 92 insertions(+), 468 deletions(-)

diff --git a/airavata-api/src/main/java/org/apache/airavata/credential/store/server/CredentialStoreServerHandler.java b/airavata-api/src/main/java/org/apache/airavata/credential/store/server/CredentialStoreServerHandler.java
index 113d2f770e..bef4b1813a 100644
--- a/airavata-api/src/main/java/org/apache/airavata/credential/store/server/CredentialStoreServerHandler.java
+++ b/airavata-api/src/main/java/org/apache/airavata/credential/store/server/CredentialStoreServerHandler.java
@@ -19,59 +19,28 @@
 */
 package org.apache.airavata.credential.store.server;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
 import java.sql.SQLException;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.List;
+import java.util.Map;
 import org.apache.airavata.common.exception.ApplicationSettingsException;
-import org.apache.airavata.common.utils.DBInitializer;
-import org.apache.airavata.common.utils.DBUtil;
-import org.apache.airavata.common.utils.ServerSettings;
 import org.apache.airavata.credential.store.cpi.CredentialStoreService;
 import org.apache.airavata.credential.store.cpi.credential_store_cpiConstants;
-import org.apache.airavata.credential.store.credential.CommunityUser;
-import org.apache.airavata.credential.store.credential.Credential;
-import org.apache.airavata.credential.store.credential.CredentialOwnerType;
 import org.apache.airavata.credential.store.store.CredentialStoreException;
-import org.apache.airavata.credential.store.store.impl.CertificateCredentialWriter;
-import org.apache.airavata.credential.store.store.impl.CredentialReaderImpl;
-import org.apache.airavata.credential.store.store.impl.SSHCredentialWriter;
-import org.apache.airavata.credential.store.store.impl.util.CredentialStoreDBInitConfig;
-import org.apache.airavata.credential.store.util.TokenGenerator;
-import org.apache.airavata.credential.store.util.Utility;
 import org.apache.airavata.model.credential.store.*;
-import org.apache.commons.codec.binary.Base64;
 import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 // import sun.security.provider.X509Factory;
 
-public class CredentialStoreServerHandler implements CredentialStoreService.Iface {
+public class CredentialStoreServerHandler implements org.apache.airavata.credential.store.cpi.CredentialStoreService.Iface {
     protected static Logger log = LoggerFactory.getLogger(CredentialStoreServerHandler.class);
-    private DBUtil dbUtil;
-    private SSHCredentialWriter sshCredentialWriter;
-    private CertificateCredentialWriter certificateCredentialWriter;
-    private CredentialReaderImpl credentialReader;
+    private org.apache.airavata.service.CredentialStoreService credentialStoreService;
 
     public CredentialStoreServerHandler()
             throws ApplicationSettingsException, IllegalAccessException, ClassNotFoundException, InstantiationException,
                     SQLException, IOException {
-        String jdbcUrl = ServerSettings.getCredentialStoreDBURL();
-        String userName = ServerSettings.getCredentialStoreDBUser();
-        String password = ServerSettings.getCredentialStoreDBPassword();
-        String driverName = ServerSettings.getCredentialStoreDBDriver();
-
-        log.debug("Starting credential store, connecting to database - " + jdbcUrl + " DB user - " + userName
-                + " driver name - " + driverName);
-        DBInitializer.initializeDB(new CredentialStoreDBInitConfig());
-
-        dbUtil = new DBUtil(jdbcUrl, userName, password, driverName);
-        sshCredentialWriter = new SSHCredentialWriter(dbUtil);
-        certificateCredentialWriter = new CertificateCredentialWriter(dbUtil);
-        credentialReader = new CredentialReaderImpl(dbUtil);
+        credentialStoreService = new org.apache.airavata.service.CredentialStoreService();
     }
 
     @Override
@@ -83,37 +52,15 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public String addSSHCredential(SSHCredential sshCredential)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential credential =
-                    new org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential();
-            credential.setGateway(sshCredential.getGatewayId());
-            credential.setPortalUserName(sshCredential.getUsername());
-            // only username and gateway id will be sent by client.
-            String token = TokenGenerator.generateToken(sshCredential.getGatewayId(), null);
-            credential.setToken(token);
-            credential.setPassphrase(String.valueOf(UUID.randomUUID()));
-            if (sshCredential.getPrivateKey() != null) {
-                credential.setPrivateKey(sshCredential.getPrivateKey().getBytes());
-            }
-            if (sshCredential.getDescription() != null) {
-                credential.setDescription(sshCredential.getDescription());
-            }
-            if (sshCredential.getPublicKey() != null) {
-                credential.setPublicKey(sshCredential.getPublicKey().getBytes());
-            }
-            if (sshCredential.getPublicKey() == null || sshCredential.getPrivateKey() == null) {
-                credential = Utility.generateKeyPair(credential);
-            }
-            credential.setCredentialOwnerType(CredentialOwnerType.GATEWAY);
-            sshCredentialWriter.writeCredentials(credential);
-            return token;
+            return credentialStoreService.addSSHCredential(sshCredential);
         } catch (CredentialStoreException e) {
             log.error("Error occurred while saving SSH Credentials.", e);
             throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
                     "Error occurred while saving SSH Credentials.");
         } catch (Exception e) {
-            log.error("Error occurred while generating key pair.", e);
+            log.error("Error occurred while saving SSH Credentials.", e);
             throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while generating key pair..");
+                    "Error occurred while saving SSH Credentials.");
         }
     }
 
@@ -121,37 +68,15 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public String addCertificateCredential(CertificateCredential certificateCredential)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential credential =
-                    new org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential();
-            credential.setPortalUserName(
-                    certificateCredential.getCommunityUser().getUsername());
-            credential.setCommunityUser(new CommunityUser(
-                    certificateCredential.getCommunityUser().getGatewayName(),
-                    certificateCredential.getCommunityUser().getUsername(),
-                    certificateCredential.getCommunityUser().getUserEmail()));
-            String token = TokenGenerator.generateToken(
-                    certificateCredential.getCommunityUser().getGatewayName(), null);
-            credential.setToken(token);
-            Base64 encoder = new Base64(64);
-            byte[] decoded = encoder.decode(certificateCredential
-                    .getX509Cert()
-                    .replaceAll("-----BEGIN CERTIFICATE-----", "")
-                    .replaceAll("-----END CERTIFICATE-----", ""));
-            CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            X509Certificate certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(decoded));
-            X509Certificate[] certificates = new X509Certificate[1];
-            certificates[0] = certificate;
-            credential.setCertificates(certificates);
-            certificateCredentialWriter.writeCredentials(credential);
-            return token;
+            return credentialStoreService.addCertificateCredential(certificateCredential);
         } catch (CredentialStoreException e) {
             log.error("Error occurred while saving Certificate Credentials.", e);
             throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
                     "Error occurred while saving Certificate Credentials.");
         } catch (Exception e) {
-            log.error("Error occurred while converting to X509 certificate.", e);
+            log.error("Error occurred while saving Certificate Credentials.", e);
             throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while converting to X509 certificate..");
+                    "Error occurred while saving Certificate Credentials.");
         }
     }
 
@@ -159,25 +84,15 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public String addPasswordCredential(PasswordCredential passwordCredential)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            org.apache.airavata.credential.store.credential.impl.password.PasswordCredential credential =
-                    new org.apache.airavata.credential.store.credential.impl.password.PasswordCredential();
-            credential.setGateway(passwordCredential.getGatewayId());
-            credential.setPortalUserName(passwordCredential.getPortalUserName());
-            credential.setUserName(passwordCredential.getLoginUserName());
-            credential.setPassword(passwordCredential.getPassword());
-            credential.setDescription(passwordCredential.getDescription());
-            String token = TokenGenerator.generateToken(passwordCredential.getGatewayId(), null);
-            credential.setToken(token);
-            sshCredentialWriter.writeCredentials(credential);
-            return token;
+            return credentialStoreService.addPasswordCredential(passwordCredential);
         } catch (CredentialStoreException e) {
             log.error("Error occurred while saving PWD Credentials.", e);
             throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
                     "Error occurred while saving PWD Credentials.");
         } catch (Exception e) {
-            log.error("Error occurred while registering PWD Credentials.", e);
+            log.error("Error occurred while saving PWD Credentials.", e);
             throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while registering PWD Credentials..");
+                    "Error occurred while saving PWD Credentials.");
         }
     }
 
@@ -185,29 +100,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public SSHCredential getSSHCredential(String tokenId, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            Credential credential = credentialReader.getCredential(gatewayId, tokenId);
-            if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential
-                    && !(credential
-                            instanceof
-                            org.apache.airavata.credential.store.credential.impl.password.PasswordCredential)) {
-                org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential credential1 =
-                        (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential;
-                SSHCredential sshCredential = new SSHCredential();
-                sshCredential.setUsername(credential1.getPortalUserName());
-                sshCredential.setGatewayId(credential1.getGateway());
-                sshCredential.setPublicKey(new String(credential1.getPublicKey()));
-                sshCredential.setPrivateKey(new String(credential1.getPrivateKey()));
-                sshCredential.setPassphrase(credential1.getPassphrase());
-                sshCredential.setToken(credential1.getToken());
-                sshCredential.setPersistedTime(
-                        credential1.getCertificateRequestedTime().getTime());
-                sshCredential.setDescription(credential1.getDescription());
-                return sshCredential;
-            } else {
-                log.info("Could not find SSH credentials for token - " + tokenId + " and " + "gateway id - "
-                        + gatewayId);
-                return null;
-            }
+            return credentialStoreService.getSSHCredential(tokenId, gatewayId);
         } catch (CredentialStoreException e) {
             log.error(
                     "Error occurred while retrieving SSH credentialfor token - " + tokenId + " and gateway id - "
@@ -223,20 +116,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public CredentialSummary getCredentialSummary(String tokenId, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            Credential credential = credentialReader.getCredential(gatewayId, tokenId);
-            if (isSSHCredential(credential)) {
-                return convertToCredentialSummary(
-                        (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential);
-            } else if (isCertificateCredential(credential)) {
-                return convertToCredentialSummary(
-                        (org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential)
-                                credential);
-            } else if (isPasswordCredential(credential)) {
-                return convertToCredentialSummary(
-                        (org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) credential);
-            }
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Unrecognized type of credential for token: " + tokenId);
+            return credentialStoreService.getCredentialSummary(tokenId, gatewayId);
         } catch (CredentialStoreException e) {
             final String msg = "Error occurred while retrieving credential summary for token - " + tokenId
                     + " and gateway id - " + gatewayId;
@@ -250,32 +130,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
             SummaryType type, List<String> accessibleTokenIds, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            List<Credential> credentials =
-                    credentialReader.getAllAccessibleCredentialsPerGateway(gatewayId, accessibleTokenIds);
-            if (type.equals(SummaryType.SSH)) {
-                return credentials.stream()
-                        .filter(this::isSSHCredential)
-                        .map(cred -> (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) cred)
-                        .map(cred -> convertToCredentialSummary(cred))
-                        .collect(Collectors.toList());
-            } else if (type.equals(SummaryType.CERT)) {
-                return credentials.stream()
-                        .filter(this::isCertificateCredential)
-                        .map(cred ->
-                                (org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential)
-                                        cred)
-                        .map(cred -> convertToCredentialSummary(cred))
-                        .collect(Collectors.toList());
-            } else if (type.equals(SummaryType.PASSWD)) {
-                return credentials.stream()
-                        .filter(this::isPasswordCredential)
-                        .map(cred ->
-                                (org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) cred)
-                        .map(cred -> convertToCredentialSummary(cred))
-                        .collect(Collectors.toList());
-            } else {
-                throw new RuntimeException("Summary Type " + type + " is not supported.");
-            }
+            return credentialStoreService.getAllCredentialSummaries(type, accessibleTokenIds, gatewayId);
         } catch (CredentialStoreException e) {
             final String msg = "Error occurred while retrieving " + type + " credential Summary for tokens - "
                     + accessibleTokenIds + " and gateway id - " + gatewayId;
@@ -284,93 +139,12 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
         }
     }
 
-    private boolean isSSHCredential(Credential cred) {
-        return cred instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential
-                && !(cred instanceof org.apache.airavata.credential.store.credential.impl.password.PasswordCredential);
-    }
-
-    private boolean isCertificateCredential(Credential cred) {
-        return cred instanceof org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential;
-    }
-
-    private boolean isPasswordCredential(Credential cred) {
-        return cred instanceof org.apache.airavata.credential.store.credential.impl.password.PasswordCredential;
-    }
-
-    private CredentialSummary convertToCredentialSummary(
-            org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential cred) {
-        CredentialSummary credentialSummary = new CredentialSummary();
-        credentialSummary.setType(SummaryType.SSH);
-        credentialSummary.setUsername(cred.getPortalUserName());
-        credentialSummary.setGatewayId(cred.getGateway());
-        credentialSummary.setPublicKey(new String(cred.getPublicKey()));
-        credentialSummary.setToken(cred.getToken());
-        credentialSummary.setPersistedTime(cred.getCertificateRequestedTime().getTime());
-        credentialSummary.setDescription(cred.getDescription());
-        return credentialSummary;
-    }
-
-    private CredentialSummary convertToCredentialSummary(
-            org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential cred) {
-        CredentialSummary credentialSummary = new CredentialSummary();
-        credentialSummary.setType(SummaryType.CERT);
-        credentialSummary.setUsername(cred.getPortalUserName());
-        // FIXME: need to get gatewayId for CertificateCredentials
-        credentialSummary.setGatewayId("");
-        // FIXME: get the public key? Or what would be appropriate for a summary of a CertificateCredential?
-        //        credentialSummary.setPublicKey(new String(cred.getPublicKey()));
-        credentialSummary.setToken(cred.getToken());
-        credentialSummary.setPersistedTime(cred.getCertificateRequestedTime().getTime());
-        credentialSummary.setDescription(cred.getDescription());
-        return credentialSummary;
-    }
-
-    private CredentialSummary convertToCredentialSummary(
-            org.apache.airavata.credential.store.credential.impl.password.PasswordCredential cred) {
-        CredentialSummary credentialSummary = new CredentialSummary();
-        credentialSummary.setType(SummaryType.PASSWD);
-        credentialSummary.setUsername(cred.getPortalUserName());
-        credentialSummary.setGatewayId(cred.getGateway());
-        credentialSummary.setToken(cred.getToken());
-        credentialSummary.setPersistedTime(cred.getCertificateRequestedTime().getTime());
-        credentialSummary.setDescription(cred.getDescription());
-        return credentialSummary;
-    }
 
     @Override
     public CertificateCredential getCertificateCredential(String tokenId, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            Credential credential = credentialReader.getCredential(gatewayId, tokenId);
-            if (credential
-                    instanceof org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential) {
-                org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential credential1 =
-                        (org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential)
-                                credential;
-                CertificateCredential certificateCredential = new CertificateCredential();
-                org.apache.airavata.model.credential.store.CommunityUser communityUser =
-                        new org.apache.airavata.model.credential.store.CommunityUser();
-                communityUser.setGatewayName(credential1.getCommunityUser().getGatewayName());
-                communityUser.setUsername(credential1.getCommunityUser().getUserName());
-                communityUser.setUserEmail(credential1.getCommunityUser().getUserEmail());
-                certificateCredential.setCommunityUser(communityUser);
-                certificateCredential.setToken(credential1.getToken());
-                certificateCredential.setLifeTime(credential1.getLifeTime());
-                certificateCredential.setNotAfter(credential1.getNotAfter());
-                certificateCredential.setNotBefore(credential1.getNotBefore());
-                certificateCredential.setPersistedTime(
-                        credential1.getCertificateRequestedTime().getTime());
-                if (credential1.getPrivateKey() != null) {
-                    certificateCredential.setPrivateKey(
-                            credential1.getPrivateKey().toString());
-                }
-                certificateCredential.setX509Cert(credential1.getCertificates()[0].toString());
-                return certificateCredential;
-            } else {
-                log.info("Could not find Certificate credentials for token - " + tokenId + " and " + "gateway id - "
-                        + gatewayId);
-                return null;
-            }
+            return credentialStoreService.getCertificateCredential(tokenId, gatewayId);
         } catch (CredentialStoreException e) {
             log.error(
                     "Error occurred while retrieving Certificate credential for token - " + tokenId
@@ -386,26 +160,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public PasswordCredential getPasswordCredential(String tokenId, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            Credential credential = credentialReader.getCredential(gatewayId, tokenId);
-            if (credential
-                    instanceof org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) {
-                org.apache.airavata.credential.store.credential.impl.password.PasswordCredential credential1 =
-                        (org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) credential;
-                PasswordCredential pwdCredential = new PasswordCredential();
-                pwdCredential.setGatewayId(credential1.getGateway());
-                pwdCredential.setPortalUserName(credential1.getPortalUserName());
-                pwdCredential.setLoginUserName(credential1.getUserName());
-                pwdCredential.setPassword(credential1.getPassword());
-                pwdCredential.setDescription(credential1.getDescription());
-                pwdCredential.setToken(credential1.getToken());
-                pwdCredential.setPersistedTime(
-                        credential1.getCertificateRequestedTime().getTime());
-                return pwdCredential;
-            } else {
-                log.info("Could not find PWD credentials for token - " + tokenId + " and " + "gateway id - "
-                        + gatewayId);
-                return null;
-            }
+            return credentialStoreService.getPasswordCredential(tokenId, gatewayId);
         } catch (CredentialStoreException e) {
             log.error(
                     "Error occurred while retrieving PWD credentialfor token - " + tokenId + " and gateway id - "
@@ -421,41 +176,12 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     @Deprecated
     public List<CredentialSummary> getAllCredentialSummaryForGateway(SummaryType type, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
-        if (type.equals(SummaryType.SSH)) {
-            Map<String, String> sshKeyMap = new HashMap<>();
-            List<CredentialSummary> summaryList = new ArrayList<>();
-            try {
-                List<Credential> allCredentials = credentialReader.getAllCredentialsPerGateway(gatewayId);
-                if (allCredentials != null && !allCredentials.isEmpty()) {
-                    for (Credential credential : allCredentials) {
-                        if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential
-                                && !(credential
-                                        instanceof
-                                        org.apache.airavata.credential.store.credential.impl.password
-                                                .PasswordCredential)
-                                && credential.getCredentialOwnerType() == CredentialOwnerType.GATEWAY) {
-                            org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential sshCredential =
-                                    (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential;
-                            CredentialSummary sshCredentialSummary = new CredentialSummary();
-                            sshCredentialSummary.setType(SummaryType.SSH);
-                            sshCredentialSummary.setToken(sshCredential.getToken());
-                            sshCredentialSummary.setUsername(sshCredential.getPortalUserName());
-                            sshCredentialSummary.setGatewayId(sshCredential.getGateway());
-                            sshCredentialSummary.setDescription(sshCredential.getDescription());
-                            sshCredentialSummary.setPublicKey(new String(sshCredential.getPublicKey()));
-                            summaryList.add(sshCredentialSummary);
-                        }
-                    }
-                }
-            } catch (CredentialStoreException e) {
-                log.error("Error occurred while retrieving credential Summary", e);
-                throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                        "Error occurred while retrieving credential Summary");
-            }
-            return summaryList;
-        } else {
-            log.info("Summay Type" + type.toString() + " not supported for gateway id - " + gatewayId);
-            return null;
+        try {
+            return credentialStoreService.getAllCredentialSummaryForGateway(type, gatewayId);
+        } catch (CredentialStoreException e) {
+            log.error("Error occurred while retrieving credential Summary", e);
+            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+                    "Error occurred while retrieving credential Summary");
         }
     }
 
@@ -464,54 +190,12 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public List<CredentialSummary> getAllCredentialSummaryForUserInGateway(
             SummaryType type, String gatewayId, String userId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
-        if (type.equals(SummaryType.SSH)) {
-            Map<String, String> sshKeyMap = new HashMap<>();
-            List<CredentialSummary> summaryList = new ArrayList<>();
-            try {
-                List<Credential> allCredentials = credentialReader.getAllCredentials();
-                if (allCredentials != null && !allCredentials.isEmpty()) {
-                    for (Credential credential : allCredentials) {
-                        if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential
-                                && !(credential
-                                        instanceof
-                                        org.apache.airavata.credential.store.credential.impl.password
-                                                .PasswordCredential)) {
-                            org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential sshCredential =
-                                    (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential;
-                            String portalUserName = sshCredential.getPortalUserName();
-                            String gateway = sshCredential.getGateway();
-                            if (portalUserName != null && gateway != null) {
-                                if (portalUserName.equals(userId)
-                                        && gateway.equals(gatewayId)
-                                        && sshCredential.getCredentialOwnerType() == CredentialOwnerType.USER) {
-                                    org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential
-                                            sshCredentialKey =
-                                                    (org.apache.airavata.credential.store.credential.impl.ssh
-                                                                    .SSHCredential)
-                                                            credential;
-                                    CredentialSummary sshCredentialSummary = new CredentialSummary();
-                                    sshCredentialSummary.setType(SummaryType.SSH);
-                                    sshCredentialSummary.setToken(sshCredentialKey.getToken());
-                                    sshCredentialSummary.setUsername(sshCredentialKey.getPortalUserName());
-                                    sshCredentialSummary.setGatewayId(sshCredentialKey.getGateway());
-                                    sshCredentialSummary.setDescription(sshCredentialKey.getDescription());
-                                    sshCredentialSummary.setPublicKey(new String(sshCredentialKey.getPublicKey()));
-                                    summaryList.add(sshCredentialSummary);
-                                }
-                            }
-                        }
-                    }
-                }
-            } catch (CredentialStoreException e) {
-                log.error("Error occurred while retrieving credential Summary", e);
-                throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                        "Error occurred while retrieving credential Summary");
-            }
-            return summaryList;
-        } else {
-            log.info("Summay Type" + type.toString() + " not supported for user Id - " + userId + " and "
-                    + "gateway id - " + gatewayId);
-            return null;
+        try {
+            return credentialStoreService.getAllCredentialSummaryForUserInGateway(type, gatewayId, userId);
+        } catch (CredentialStoreException e) {
+            log.error("Error occurred while retrieving credential Summary", e);
+            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+                    "Error occurred while retrieving credential Summary");
         }
     }
 
@@ -519,37 +203,20 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     @Deprecated
     public Map<String, String> getAllPWDCredentialsForGateway(String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
-        Map<String, String> pwdCredMap = new HashMap<>();
         try {
-            List<Credential> allCredentials = credentialReader.getAllCredentialsPerGateway(gatewayId);
-            if (allCredentials != null && !allCredentials.isEmpty()) {
-                for (Credential credential : allCredentials) {
-                    if (credential
-                            instanceof
-                            org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) {
-                        org.apache.airavata.credential.store.credential.impl.password.PasswordCredential pwdCredential =
-                                (org.apache.airavata.credential.store.credential.impl.password.PasswordCredential)
-                                        credential;
-                        pwdCredMap.put(
-                                pwdCredential.getToken(),
-                                pwdCredential.getDescription() == null ? "" : pwdCredential.getDescription());
-                    }
-                }
-            }
+            return credentialStoreService.getAllPWDCredentialsForGateway(gatewayId);
         } catch (CredentialStoreException e) {
             log.error("Error occurred while retrieving credentials", e);
             throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
                     "Error occurred while retrieving credentials");
         }
-        return pwdCredMap;
     }
 
     @Override
     public boolean deleteSSHCredential(String tokenId, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            credentialReader.removeCredentials(gatewayId, tokenId);
-            return true;
+            return credentialStoreService.deleteSSHCredential(tokenId, gatewayId);
         } catch (CredentialStoreException e) {
             log.error(
                     "Error occurred while deleting SSH credential for token - " + tokenId + " and gateway id - "
@@ -565,8 +232,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
     public boolean deletePWDCredential(String tokenId, String gatewayId)
             throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
         try {
-            credentialReader.removeCredentials(gatewayId, tokenId);
-            return true;
+            return credentialStoreService.deletePWDCredential(tokenId, gatewayId);
         } catch (CredentialStoreException e) {
             log.error(
                     "Error occurred while deleting PWD credential for token - " + tokenId + " and gateway id - "
diff --git a/airavata-api/src/main/java/org/apache/airavata/credential/store/server/CredentialStoreServerHandler.java b/airavata-api/src/main/java/org/apache/airavata/service/CredentialStoreService.java
similarity index 81%
copy from airavata-api/src/main/java/org/apache/airavata/credential/store/server/CredentialStoreServerHandler.java
copy to airavata-api/src/main/java/org/apache/airavata/service/CredentialStoreService.java
index 113d2f770e..129de089f2 100644
--- a/airavata-api/src/main/java/org/apache/airavata/credential/store/server/CredentialStoreServerHandler.java
+++ b/airavata-api/src/main/java/org/apache/airavata/service/CredentialStoreService.java
@@ -17,7 +17,7 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-package org.apache.airavata.credential.store.server;
+package org.apache.airavata.service;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -30,8 +30,6 @@ import org.apache.airavata.common.exception.ApplicationSettingsException;
 import org.apache.airavata.common.utils.DBInitializer;
 import org.apache.airavata.common.utils.DBUtil;
 import org.apache.airavata.common.utils.ServerSettings;
-import org.apache.airavata.credential.store.cpi.CredentialStoreService;
-import org.apache.airavata.credential.store.cpi.credential_store_cpiConstants;
 import org.apache.airavata.credential.store.credential.CommunityUser;
 import org.apache.airavata.credential.store.credential.Credential;
 import org.apache.airavata.credential.store.credential.CredentialOwnerType;
@@ -44,19 +42,18 @@ import org.apache.airavata.credential.store.util.TokenGenerator;
 import org.apache.airavata.credential.store.util.Utility;
 import org.apache.airavata.model.credential.store.*;
 import org.apache.commons.codec.binary.Base64;
-import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-// import sun.security.provider.X509Factory;
 
-public class CredentialStoreServerHandler implements CredentialStoreService.Iface {
-    protected static Logger log = LoggerFactory.getLogger(CredentialStoreServerHandler.class);
+public class CredentialStoreService {
+    private static final Logger logger = LoggerFactory.getLogger(CredentialStoreService.class);
+    
     private DBUtil dbUtil;
     private SSHCredentialWriter sshCredentialWriter;
     private CertificateCredentialWriter certificateCredentialWriter;
     private CredentialReaderImpl credentialReader;
 
-    public CredentialStoreServerHandler()
+    public CredentialStoreService()
             throws ApplicationSettingsException, IllegalAccessException, ClassNotFoundException, InstantiationException,
                     SQLException, IOException {
         String jdbcUrl = ServerSettings.getCredentialStoreDBURL();
@@ -64,7 +61,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
         String password = ServerSettings.getCredentialStoreDBPassword();
         String driverName = ServerSettings.getCredentialStoreDBDriver();
 
-        log.debug("Starting credential store, connecting to database - " + jdbcUrl + " DB user - " + userName
+        logger.debug("Starting credential store, connecting to database - " + jdbcUrl + " DB user - " + userName
                 + " driver name - " + driverName);
         DBInitializer.initializeDB(new CredentialStoreDBInitConfig());
 
@@ -74,14 +71,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
         credentialReader = new CredentialReaderImpl(dbUtil);
     }
 
-    @Override
-    public String getAPIVersion() throws TException {
-        return credential_store_cpiConstants.CS_CPI_VERSION;
-    }
-
-    @Override
-    public String addSSHCredential(SSHCredential sshCredential)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public String addSSHCredential(SSHCredential sshCredential) throws CredentialStoreException {
         try {
             org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential credential =
                     new org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential();
@@ -107,19 +97,15 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
             sshCredentialWriter.writeCredentials(credential);
             return token;
         } catch (CredentialStoreException e) {
-            log.error("Error occurred while saving SSH Credentials.", e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while saving SSH Credentials.");
+            logger.error("Error occurred while saving SSH Credentials.", e);
+            throw new CredentialStoreException("Error occurred while saving SSH Credentials.");
         } catch (Exception e) {
-            log.error("Error occurred while generating key pair.", e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while generating key pair..");
+            logger.error("Error occurred while generating key pair.", e);
+            throw new CredentialStoreException("Error occurred while generating key pair..");
         }
     }
 
-    @Override
-    public String addCertificateCredential(CertificateCredential certificateCredential)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public String addCertificateCredential(CertificateCredential certificateCredential) throws CredentialStoreException {
         try {
             org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential credential =
                     new org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential();
@@ -145,19 +131,15 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
             certificateCredentialWriter.writeCredentials(credential);
             return token;
         } catch (CredentialStoreException e) {
-            log.error("Error occurred while saving Certificate Credentials.", e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while saving Certificate Credentials.");
+            logger.error("Error occurred while saving Certificate Credentials.", e);
+            throw new CredentialStoreException("Error occurred while saving Certificate Credentials.");
         } catch (Exception e) {
-            log.error("Error occurred while converting to X509 certificate.", e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while converting to X509 certificate..");
+            logger.error("Error occurred while converting to X509 certificate.", e);
+            throw new CredentialStoreException("Error occurred while converting to X509 certificate..");
         }
     }
 
-    @Override
-    public String addPasswordCredential(PasswordCredential passwordCredential)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public String addPasswordCredential(PasswordCredential passwordCredential) throws CredentialStoreException {
         try {
             org.apache.airavata.credential.store.credential.impl.password.PasswordCredential credential =
                     new org.apache.airavata.credential.store.credential.impl.password.PasswordCredential();
@@ -171,19 +153,15 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
             sshCredentialWriter.writeCredentials(credential);
             return token;
         } catch (CredentialStoreException e) {
-            log.error("Error occurred while saving PWD Credentials.", e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while saving PWD Credentials.");
+            logger.error("Error occurred while saving PWD Credentials.", e);
+            throw new CredentialStoreException("Error occurred while saving PWD Credentials.");
         } catch (Exception e) {
-            log.error("Error occurred while registering PWD Credentials.", e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while registering PWD Credentials..");
+            logger.error("Error occurred while registering PWD Credentials.", e);
+            throw new CredentialStoreException("Error occurred while registering PWD Credentials..");
         }
     }
 
-    @Override
-    public SSHCredential getSSHCredential(String tokenId, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public SSHCredential getSSHCredential(String tokenId, String gatewayId) throws CredentialStoreException {
         try {
             Credential credential = credentialReader.getCredential(gatewayId, tokenId);
             if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential
@@ -204,24 +182,22 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
                 sshCredential.setDescription(credential1.getDescription());
                 return sshCredential;
             } else {
-                log.info("Could not find SSH credentials for token - " + tokenId + " and " + "gateway id - "
+                logger.info("Could not find SSH credentials for token - " + tokenId + " and " + "gateway id - "
                         + gatewayId);
                 return null;
             }
         } catch (CredentialStoreException e) {
-            log.error(
+            logger.error(
                     "Error occurred while retrieving SSH credentialfor token - " + tokenId + " and gateway id - "
                             + gatewayId,
                     e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+            throw new CredentialStoreException(
                     "Error occurred while retrieving SSH credential for token - " + tokenId + " and gateway id - "
                             + gatewayId);
         }
     }
 
-    @Override
-    public CredentialSummary getCredentialSummary(String tokenId, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public CredentialSummary getCredentialSummary(String tokenId, String gatewayId) throws CredentialStoreException {
         try {
             Credential credential = credentialReader.getCredential(gatewayId, tokenId);
             if (isSSHCredential(credential)) {
@@ -235,20 +211,18 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
                 return convertToCredentialSummary(
                         (org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) credential);
             }
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+            throw new CredentialStoreException(
                     "Unrecognized type of credential for token: " + tokenId);
         } catch (CredentialStoreException e) {
             final String msg = "Error occurred while retrieving credential summary for token - " + tokenId
                     + " and gateway id - " + gatewayId;
-            log.error(msg, e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(msg);
+            logger.error(msg, e);
+            throw new CredentialStoreException(msg);
         }
     }
 
-    @Override
     public List<CredentialSummary> getAllCredentialSummaries(
-            SummaryType type, List<String> accessibleTokenIds, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+            SummaryType type, List<String> accessibleTokenIds, String gatewayId) throws CredentialStoreException {
         try {
             List<Credential> credentials =
                     credentialReader.getAllAccessibleCredentialsPerGateway(gatewayId, accessibleTokenIds);
@@ -279,8 +253,8 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
         } catch (CredentialStoreException e) {
             final String msg = "Error occurred while retrieving " + type + " credential Summary for tokens - "
                     + accessibleTokenIds + " and gateway id - " + gatewayId;
-            log.error(msg, e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(msg);
+            logger.error(msg, e);
+            throw new CredentialStoreException(msg);
         }
     }
 
@@ -337,9 +311,7 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
         return credentialSummary;
     }
 
-    @Override
-    public CertificateCredential getCertificateCredential(String tokenId, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public CertificateCredential getCertificateCredential(String tokenId, String gatewayId) throws CredentialStoreException {
         try {
             Credential credential = credentialReader.getCredential(gatewayId, tokenId);
             if (credential
@@ -367,24 +339,22 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
                 certificateCredential.setX509Cert(credential1.getCertificates()[0].toString());
                 return certificateCredential;
             } else {
-                log.info("Could not find Certificate credentials for token - " + tokenId + " and " + "gateway id - "
+                logger.info("Could not find Certificate credentials for token - " + tokenId + " and " + "gateway id - "
                         + gatewayId);
                 return null;
             }
         } catch (CredentialStoreException e) {
-            log.error(
+            logger.error(
                     "Error occurred while retrieving Certificate credential for token - " + tokenId
                             + " and gateway id - " + gatewayId,
                     e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+            throw new CredentialStoreException(
                     "Error occurred while retrieving Certificate credential for token - " + tokenId
                             + " and gateway id - " + gatewayId);
         }
     }
 
-    @Override
-    public PasswordCredential getPasswordCredential(String tokenId, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public PasswordCredential getPasswordCredential(String tokenId, String gatewayId) throws CredentialStoreException {
         try {
             Credential credential = credentialReader.getCredential(gatewayId, tokenId);
             if (credential
@@ -402,25 +372,23 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
                         credential1.getCertificateRequestedTime().getTime());
                 return pwdCredential;
             } else {
-                log.info("Could not find PWD credentials for token - " + tokenId + " and " + "gateway id - "
+                logger.info("Could not find PWD credentials for token - " + tokenId + " and " + "gateway id - "
                         + gatewayId);
                 return null;
             }
         } catch (CredentialStoreException e) {
-            log.error(
+            logger.error(
                     "Error occurred while retrieving PWD credentialfor token - " + tokenId + " and gateway id - "
                             + gatewayId,
                     e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+            throw new CredentialStoreException(
                     "Error occurred while retrieving PWD credential for token - " + tokenId + " and gateway id - "
                             + gatewayId);
         }
     }
 
-    @Override
     @Deprecated
-    public List<CredentialSummary> getAllCredentialSummaryForGateway(SummaryType type, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public List<CredentialSummary> getAllCredentialSummaryForGateway(SummaryType type, String gatewayId) throws CredentialStoreException {
         if (type.equals(SummaryType.SSH)) {
             Map<String, String> sshKeyMap = new HashMap<>();
             List<CredentialSummary> summaryList = new ArrayList<>();
@@ -448,22 +416,19 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
                     }
                 }
             } catch (CredentialStoreException e) {
-                log.error("Error occurred while retrieving credential Summary", e);
-                throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                        "Error occurred while retrieving credential Summary");
+                logger.error("Error occurred while retrieving credential Summary", e);
+                throw new CredentialStoreException("Error occurred while retrieving credential Summary");
             }
             return summaryList;
         } else {
-            log.info("Summay Type" + type.toString() + " not supported for gateway id - " + gatewayId);
+            logger.info("Summay Type" + type.toString() + " not supported for gateway id - " + gatewayId);
             return null;
         }
     }
 
-    @Override
     @Deprecated
     public List<CredentialSummary> getAllCredentialSummaryForUserInGateway(
-            SummaryType type, String gatewayId, String userId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+            SummaryType type, String gatewayId, String userId) throws CredentialStoreException {
         if (type.equals(SummaryType.SSH)) {
             Map<String, String> sshKeyMap = new HashMap<>();
             List<CredentialSummary> summaryList = new ArrayList<>();
@@ -503,22 +468,19 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
                     }
                 }
             } catch (CredentialStoreException e) {
-                log.error("Error occurred while retrieving credential Summary", e);
-                throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                        "Error occurred while retrieving credential Summary");
+                logger.error("Error occurred while retrieving credential Summary", e);
+                throw new CredentialStoreException("Error occurred while retrieving credential Summary");
             }
             return summaryList;
         } else {
-            log.info("Summay Type" + type.toString() + " not supported for user Id - " + userId + " and "
+            logger.info("Summay Type" + type.toString() + " not supported for user Id - " + userId + " and "
                     + "gateway id - " + gatewayId);
             return null;
         }
     }
 
-    @Override
     @Deprecated
-    public Map<String, String> getAllPWDCredentialsForGateway(String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public Map<String, String> getAllPWDCredentialsForGateway(String gatewayId) throws CredentialStoreException {
         Map<String, String> pwdCredMap = new HashMap<>();
         try {
             List<Credential> allCredentials = credentialReader.getAllCredentialsPerGateway(gatewayId);
@@ -537,44 +499,40 @@ public class CredentialStoreServerHandler implements CredentialStoreService.Ifac
                 }
             }
         } catch (CredentialStoreException e) {
-            log.error("Error occurred while retrieving credentials", e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
-                    "Error occurred while retrieving credentials");
+            logger.error("Error occurred while retrieving credentials", e);
+            throw new CredentialStoreException("Error occurred while retrieving credentials");
         }
         return pwdCredMap;
     }
 
-    @Override
-    public boolean deleteSSHCredential(String tokenId, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public boolean deleteSSHCredential(String tokenId, String gatewayId) throws CredentialStoreException {
         try {
             credentialReader.removeCredentials(gatewayId, tokenId);
             return true;
         } catch (CredentialStoreException e) {
-            log.error(
+            logger.error(
                     "Error occurred while deleting SSH credential for token - " + tokenId + " and gateway id - "
                             + gatewayId,
                     e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+            throw new CredentialStoreException(
                     "Error occurred while deleting SSH credential for token - " + tokenId + " and gateway id - "
                             + gatewayId);
         }
     }
 
-    @Override
-    public boolean deletePWDCredential(String tokenId, String gatewayId)
-            throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException {
+    public boolean deletePWDCredential(String tokenId, String gatewayId) throws CredentialStoreException {
         try {
             credentialReader.removeCredentials(gatewayId, tokenId);
             return true;
         } catch (CredentialStoreException e) {
-            log.error(
+            logger.error(
                     "Error occurred while deleting PWD credential for token - " + tokenId + " and gateway id - "
                             + gatewayId,
                     e);
-            throw new org.apache.airavata.credential.store.exception.CredentialStoreException(
+            throw new CredentialStoreException(
                     "Error occurred while deleting PWD credential for token - " + tokenId + " and gateway id - "
                             + gatewayId);
         }
     }
 }
+