Repository: airavata Updated Branches: refs/heads/orchestratorJobThrottleFeature eed05a434 -> 4070d5b25
updated pom to use jglobus 2.1.0 and added bes related handlers Project: http://git-wip-us.apache.org/repos/asf/airavata/repo Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/7a4f2021 Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/7a4f2021 Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/7a4f2021 Branch: refs/heads/orchestratorJobThrottleFeature Commit: 7a4f2021db03021574c3072f04028f5a4c3a64b2 Parents: 72f3524 Author: msmemon <[email protected]> Authored: Fri Sep 26 17:17:53 2014 +0200 Committer: msmemon <[email protected]> Committed: Fri Sep 26 17:17:53 2014 +0200 ---------------------------------------------------------------------- .../gfac/bes/handlers/AbstractSMSHandler.java | 129 +++++++++ .../gfac/bes/handlers/SMSByteIOInHandler.java | 5 + .../gfac/bes/handlers/SMSByteIOOutHandler.java | 5 + .../gfac/bes/handlers/SMSDirectoryHandler.java | 5 + .../bes/security/UNICORESecurityContext.java | 267 +++++++++++++++++++ .../airavata/gfac/bes/utils/ActivityInfo.java | 30 +++ .../airavata/gfac/bes/utils/BESConstants.java | 13 + .../gfac/bes/utils/DataServiceInfo.java | 62 +++++ 8 files changed, 516 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/AbstractSMSHandler.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/AbstractSMSHandler.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/AbstractSMSHandler.java new file mode 100644 index 0000000..fef4e97 --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/AbstractSMSHandler.java @@ -0,0 +1,129 @@ +package org.apache.airavata.gfac.bes.handlers; + +import java.util.Map; +import java.util.Properties; + +import org.apache.airavata.common.exception.ApplicationSettingsException; +import org.apache.airavata.gfac.GFacException; +import org.apache.airavata.gfac.bes.security.UNICORESecurityContext; +import org.apache.airavata.gfac.bes.utils.BESConstants; +import org.apache.airavata.gfac.bes.utils.DataTransferrer; +import org.apache.airavata.gfac.bes.utils.StorageCreator; +import org.apache.airavata.gfac.core.context.JobExecutionContext; +import org.apache.airavata.gfac.core.handler.GFacHandler; +import org.apache.airavata.gfac.core.handler.GFacHandlerException; +import org.apache.airavata.schemas.gfac.JobDirectoryModeDocument.JobDirectoryMode; +import org.apache.airavata.schemas.gfac.UnicoreHostType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3.x2005.x08.addressing.EndpointReferenceType; + +import de.fzj.unicore.uas.client.StorageClient; +import eu.unicore.util.httpclient.DefaultClientConfiguration; + +public abstract class AbstractSMSHandler implements BESConstants, GFacHandler{ + + // TODO: later use AbstractHandler, which cannot be used due to error in RegistryFactory + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + protected DefaultClientConfiguration secProperties; + + protected StorageClient storageClient; + + protected DataTransferrer dataTransferrer; + + @Override + public void initProperties(Properties properties) + throws GFacHandlerException { + + } + + @Override + public void invoke(JobExecutionContext jobExecutionContext) + throws GFacHandlerException { + + // if not SMS then not to pass further + if(!isSMSEnabled(jobExecutionContext)) return; + + initSecurityProperties(jobExecutionContext); + + + + UnicoreHostType host = (UnicoreHostType) jobExecutionContext.getApplicationContext().getHostDescription() + .getType(); + String factoryUrl = host.getUnicoreBESEndPointArray()[0]; + + storageClient = null; + + if(!isSMSInstanceExisting(jobExecutionContext)) { + EndpointReferenceType eprt = EndpointReferenceType.Factory.newInstance(); + eprt.addNewAddress().setStringValue(factoryUrl); + StorageCreator storageCreator = new StorageCreator(secProperties, factoryUrl, 5, null); + try { + storageClient = storageCreator.createStorage(); + } catch (Exception e2) { + log.error("Cannot create storage.."); + throw new GFacHandlerException("Cannot create storage..", e2); + } + jobExecutionContext.setProperty(PROP_SMS_EPR, storageClient.getEPR()); + } + else { + EndpointReferenceType eprt = (EndpointReferenceType)jobExecutionContext.getProperty(PROP_SMS_EPR); + try { + storageClient = new StorageClient(eprt, secProperties); + } catch (Exception e) { + throw new GFacHandlerException("Cannot create storage..", e); + } + } + dataTransferrer = new DataTransferrer(jobExecutionContext, storageClient); + } + + protected void initSecurityProperties(JobExecutionContext jobExecutionContext) throws GFacHandlerException{ + log.debug("Initializing SMSInHandler security properties .."); + if (secProperties != null) { + secProperties = secProperties.clone(); + return; + } + UNICORESecurityContext unicoreContext; + try { + unicoreContext = (UNICORESecurityContext) jobExecutionContext.getSecurityContext(UNICORESecurityContext.UNICORE_SECURITY_CONTEXT); + } catch (GFacException e) { + throw new GFacHandlerException(e); + } + if(log.isDebugEnabled()) { + log.debug("Generating client's default security configuration.."); + } + //TODO: check what kind of credential (server signed or myproxy) should be used + try { + secProperties = unicoreContext.getDefaultConfiguration(); + } catch (Exception e) { + throw new GFacHandlerException(e); + } + if(log.isDebugEnabled()) { + log.debug("Security properties are initialized."); + } + jobExecutionContext.setProperty(PROP_CLIENT_CONF, secProperties); + } + + protected boolean isSMSInstanceExisting(JobExecutionContext jec){ + boolean hasSMS = true; + if((null == jec.getProperty(PROP_SMS_EPR))) { + hasSMS = false; + } + return hasSMS; + } + + /** + * It checks whether the SMSByteIO protocol is used during the creation + * of the job execution context. + * */ + protected boolean isSMSEnabled(JobExecutionContext jobExecutionContext){ + if(((UnicoreHostType)jobExecutionContext.getApplicationContext().getHostDescription().getType()).getJobDirectoryMode() == JobDirectoryMode.SMS_BYTE_IO) { + return true; + } + return false; + } + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOInHandler.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOInHandler.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOInHandler.java new file mode 100644 index 0000000..286637a --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOInHandler.java @@ -0,0 +1,5 @@ +package org.apache.airavata.gfac.bes.handlers; + +public class SMSByteIOInHandler { + +} http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOOutHandler.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOOutHandler.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOOutHandler.java new file mode 100644 index 0000000..63787bc --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSByteIOOutHandler.java @@ -0,0 +1,5 @@ +package org.apache.airavata.gfac.bes.handlers; + +public class SMSByteIOOutHandler { + +} http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSDirectoryHandler.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSDirectoryHandler.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSDirectoryHandler.java new file mode 100644 index 0000000..7805097 --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/handlers/SMSDirectoryHandler.java @@ -0,0 +1,5 @@ +package org.apache.airavata.gfac.bes.handlers; + +public class SMSDirectoryHandler { + +} http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/security/UNICORESecurityContext.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/security/UNICORESecurityContext.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/security/UNICORESecurityContext.java new file mode 100644 index 0000000..690ad43 --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/security/UNICORESecurityContext.java @@ -0,0 +1,267 @@ +package org.apache.airavata.gfac.bes.security; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Random; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +import org.apache.airavata.common.exception.ApplicationSettingsException; +import org.apache.airavata.credential.store.store.CredentialReader; +import org.apache.airavata.gfac.GFacException; +import org.apache.airavata.gfac.RequestData; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.globus.gsi.gssapi.GlobusGSSCredentialImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.emi.security.authn.x509.helpers.CertificateHelpers; +import eu.emi.security.authn.x509.helpers.proxy.X509v3CertificateBuilder; +import eu.emi.security.authn.x509.impl.CertificateUtils; +import eu.emi.security.authn.x509.impl.DirectoryCertChainValidator; +import eu.emi.security.authn.x509.impl.KeyAndCertCredential; +import eu.emi.security.authn.x509.impl.X500NameUtils; +import eu.emi.security.authn.x509.impl.CertificateUtils.Encoding; +import eu.emi.security.authn.x509.impl.PEMCredential; +import eu.unicore.util.httpclient.DefaultClientConfiguration; + +public class UNICORESecurityContext extends GSISecurityContext { + + protected static final Logger log = LoggerFactory.getLogger(UNICORESecurityContext.class); + private DefaultClientConfiguration secProperties; + protected static DirectoryCertChainValidator dcValidator; + + public static final String UNICORE_SECURITY_CONTEXT = "unicore"; + + public UNICORESecurityContext(CredentialReader credentialReader, RequestData requestData) { + super(credentialReader, requestData); + } + static { + try { + dcValidator = getTrustedCerts(); + } catch (Exception e) { + log.error("Cannot construct trust validator.", e); + } + } + + /** + * Get client configuration from MyProxy credentials. + * + * @return an instance of the default client configuration + * @throws GFacException + * @throws ApplicationSettingsException + * @throws GFacProviderException + */ + public DefaultClientConfiguration getDefaultConfiguration() throws GFacException, ApplicationSettingsException { + GlobusGSSCredentialImpl gss = (GlobusGSSCredentialImpl) getGssCredentials(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + BufferedOutputStream bufos = new BufferedOutputStream(bos); + ByteArrayInputStream bis = null; + BufferedInputStream bufis = null; + try{ + gss.getX509Credential().save(bufos); + bufos.flush(); + char[] c = null; + bis = new ByteArrayInputStream(bos.toByteArray()); + bufis = new BufferedInputStream(bis); + PEMCredential cred = new PEMCredential(bufis, c); + secProperties = new DefaultClientConfiguration(dcValidator, cred); +// setExtraSettings(); + } + catch (Exception e) { + throw new GFacException(e.getMessage(), e); + } + finally{ + try { + if(bos!=null)bos.close(); + if(bufos!=null)bufos.close(); + if(bis!=null)bis.close(); + if(bufis!=null)bufis.close(); + } catch (IOException e) { + log.error("Error closing IO streams.", e); + } + } + + secProperties.getETDSettings().setExtendTrustDelegation(true); +// secProperties.setMessageLogging(true); +// secProperties.setDoSignMessage(true); +// secProperties.getETDSettings().setIssuerCertificateChain(secProperties.getCredential().getCertificateChain()); + + + + return secProperties; + } + + /** + * Get server signed credentials. Each time it is invoked new certificate + * is returned. + * + * @param userID + * @param userDN + * @param caCertPath + * @param caKeyPath + * @param caKeyPwd + * @return + * @throws GFacProviderException + */ + public DefaultClientConfiguration getServerSignedConfiguration(String userID, String userDN, String caCertPath, String caKeyPath, String caKeyPwd) throws GFacException { + try { + KeyAndCertCredential cred = generateShortLivedCertificate(userDN,caCertPath,caKeyPath,caKeyPwd); + secProperties = new DefaultClientConfiguration(dcValidator, cred); + setExtraSettings(); + } catch (Exception e) { + throw new GFacException(e.getMessage(), e); + } + + return secProperties; + } + + + private KeyAndCertCredential generateShortLivedCertificate(String userDN, + String caCertPath, String caKeyPath, String caPwd) throws Exception { + final long CredentialGoodFromOffset = 1000L * 60L * 15L; // 15 minutes + // ago + + final long startTime = System.currentTimeMillis() + - CredentialGoodFromOffset; + final long endTime = startTime + 30 * 3600 * 1000; + + String keyLengthProp = "1024"; + int keyLength = Integer.parseInt(keyLengthProp); + String signatureAlgorithm = "SHA1withRSA"; + + KeyAndCertCredential caCred = getCACredential(caCertPath, caKeyPath, + caPwd); + + KeyPairGenerator kpg = KeyPairGenerator.getInstance(caCred.getKey() + .getAlgorithm()); + kpg.initialize(keyLength); + KeyPair pair = kpg.generateKeyPair(); + + X500Principal subjectDN = new X500Principal(userDN); + Random rand = new Random(); + + SubjectPublicKeyInfo publicKeyInfo; + try { + publicKeyInfo = SubjectPublicKeyInfo + .getInstance(new ASN1InputStream(pair.getPublic() + .getEncoded()).readObject()); + } catch (IOException e) { + throw new InvalidKeyException("Can not parse the public key" + + "being included in the short lived certificate", e); + } + + X500Name issuerX500Name = CertificateHelpers.toX500Name(caCred + .getCertificate().getSubjectX500Principal()); + + X500Name subjectX500Name = CertificateHelpers.toX500Name(subjectDN); + + X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder( + issuerX500Name, new BigInteger(20, rand), new Date(startTime), + new Date(endTime), subjectX500Name, publicKeyInfo); + + AlgorithmIdentifier sigAlgId = X509v3CertificateBuilder + .extractAlgorithmId(caCred.getCertificate()); + + X509Certificate certificate = certBuilder.build(caCred.getKey(), + sigAlgId, signatureAlgorithm, null, null); + + certificate.checkValidity(new Date()); + certificate.verify(caCred.getCertificate().getPublicKey()); + KeyAndCertCredential result = new KeyAndCertCredential( + pair.getPrivate(), new X509Certificate[] { certificate, + caCred.getCertificate() }); + + return result; + } + + private KeyAndCertCredential getCACredential(String caCertPath, + String caKeyPath, String password) throws Exception { + InputStream isKey = new FileInputStream(caKeyPath); + PrivateKey pk = CertificateUtils.loadPrivateKey(isKey, Encoding.PEM, + password.toCharArray()); + + InputStream isCert = new FileInputStream(caCertPath); + X509Certificate caCert = CertificateUtils.loadCertificate(isCert, + Encoding.PEM); + + if (isKey != null) + isKey.close(); + if (isCert != null) + isCert.close(); + + return new KeyAndCertCredential(pk, new X509Certificate[] { caCert }); + } + + private static DirectoryCertChainValidator getTrustedCerts() throws Exception{ + String certLocation = getTrustedCertificatePath(); + List<String> trustedCert = new ArrayList<String>(); + trustedCert.add(certLocation + "/*.0"); + trustedCert.add(certLocation + "/*.pem"); + DirectoryCertChainValidator dcValidator = new DirectoryCertChainValidator(trustedCert, Encoding.PEM, -1, 60000, null); + return dcValidator; + } + + private void setExtraSettings(){ + secProperties.getETDSettings().setExtendTrustDelegation(true); + + secProperties.setDoSignMessage(true); + + String[] outHandlers = secProperties.getOutHandlerClassNames(); + + Set<String> outHandlerLst = null; + + // timeout in milliseconds + Properties p = secProperties.getExtraSettings(); + + if(p == null) { + p = new Properties(); + } + + p.setProperty("http.connection.timeout", "300000"); + p.setProperty("http.socket.timeout", "300000"); + + secProperties.setExtraSettings(p); + + if (outHandlers == null) { + outHandlerLst = new HashSet<String>(); + } else { + outHandlerLst = new HashSet<String>(Arrays.asList(outHandlers)); + } + + outHandlerLst.add("de.fzj.unicore.uas.security.ProxyCertOutHandler"); + + secProperties.setOutHandlerClassNames(outHandlerLst + .toArray(new String[outHandlerLst.size()])); + } + + + private String getCNFromUserDN(String userDN) { + return X500NameUtils.getAttributeValues(userDN, BCStyle.CN)[0]; + + } + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/ActivityInfo.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/ActivityInfo.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/ActivityInfo.java new file mode 100644 index 0000000..f1b3b08 --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/ActivityInfo.java @@ -0,0 +1,30 @@ +package org.apache.airavata.gfac.bes.utils; + +import java.io.Serializable; + +import org.ggf.schemas.bes.x2006.x08.besFactory.ActivityStatusType; +import org.w3.x2005.x08.addressing.EndpointReferenceType; + +public class ActivityInfo implements Serializable{ + + private static final long serialVersionUID = 1L; + + private EndpointReferenceType activityEPR; + + private ActivityStatusType activityStatusDoc; + + + public EndpointReferenceType getActivityEPR() { + return activityEPR; + } + public void setActivityEPR(EndpointReferenceType activityEPR) { + this.activityEPR = activityEPR; + } + public ActivityStatusType getActivityStatus() { + return activityStatusDoc; + } + public void setActivityStatusDoc(ActivityStatusType activityStatusDoc) { + this.activityStatusDoc = activityStatusDoc; + } + +} http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/BESConstants.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/BESConstants.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/BESConstants.java new file mode 100644 index 0000000..cbc4aad --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/BESConstants.java @@ -0,0 +1,13 @@ +package org.apache.airavata.gfac.bes.utils; + +public interface BESConstants { + + public static final String PROP_SMS_EPR = "unicore.sms.epr"; + + public static final String PROP_BES_URL = "bes.factory.url"; + + public static final String PROP_ACTIVITY_INFO = "bes.activity.info"; + + public static final String PROP_CLIENT_CONF = "bes.client.config"; + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/airavata/blob/7a4f2021/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/DataServiceInfo.java ---------------------------------------------------------------------- diff --git a/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/DataServiceInfo.java b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/DataServiceInfo.java new file mode 100644 index 0000000..b63dcb2 --- /dev/null +++ b/modules/gfac/gfac-bes/src/main/java/org/apache/airavata/gfac/bes/utils/DataServiceInfo.java @@ -0,0 +1,62 @@ +package org.apache.airavata.gfac.bes.utils; + +import java.io.Serializable; + +import org.apache.airavata.gfac.core.context.JobExecutionContext; +import org.apache.airavata.schemas.gfac.JobDirectoryModeDocument.JobDirectoryMode; +import org.apache.airavata.schemas.gfac.UnicoreHostType; +import org.w3.x2005.x08.addressing.EndpointReferenceType; + + +/** + * A value object carrying information about data service access mode. + * */ +public class DataServiceInfo implements BESConstants, Serializable { + + private static final long serialVersionUID = 1L; + + public enum DirectoryAccessMode { + GridFTP, SMSBYTEIO, RNSBYTEIO + } + + /* + * basically only uses information to hold gridftp address or an optional + * pointer to a remote StorageManagementService instance. + */ + private String dataServiceUrl; + + private DirectoryAccessMode directoryAccesMode = DirectoryAccessMode.SMSBYTEIO; + + public DataServiceInfo(JobExecutionContext c) { + JobDirectoryMode.Enum directoryAccess = ((UnicoreHostType)c.getApplicationContext().getHostDescription().getType()).getJobDirectoryMode(); + + switch(directoryAccess.intValue()) { + case JobDirectoryMode.INT_SMS_BYTE_IO: + directoryAccesMode = DirectoryAccessMode.SMSBYTEIO; + EndpointReferenceType s = (EndpointReferenceType) c + .getProperty(PROP_SMS_EPR); + dataServiceUrl = s.getAddress().getStringValue(); + break; + case JobDirectoryMode.INT_GRID_FTP: + case JobDirectoryMode.INT_RNS_BYTE_IO: + default: + directoryAccesMode = DirectoryAccessMode.GridFTP; + break; + } + + } + + public String getDataServiceUrl() { + return dataServiceUrl; + } + + public void setDataServiceUrl(String dataServiceUrl) { + this.dataServiceUrl = dataServiceUrl; + } + + public DirectoryAccessMode getDirectoryAccesMode() { + return directoryAccesMode; + } + + +} \ No newline at end of file
