├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DEVELOPING.md ├── FAQ.md ├── LICENSE.txt ├── MantaCLI.md ├── NOTICE ├── QUICKSTART.md ├── README.md ├── RELEASING.md ├── TESTING.md ├── USAGE.md ├── checkstyle.xml ├── java-manta-benchmark ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── joyent │ │ └── manta │ │ └── benchmark │ │ ├── Benchmark.java │ │ ├── EncryptingEntityBenchmark.java │ │ ├── RandomInputStream.java │ │ └── package-info.java │ └── resources │ └── logback.xml ├── java-manta-cli ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── joyent │ │ └── manta │ │ └── cli │ │ ├── MantaCLI.java │ │ └── package-info.java │ └── resources │ └── logback.xml ├── java-manta-client-kryo-serialization ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── joyent │ │ └── manta │ │ └── serialization │ │ ├── AbstractManualSerializer.java │ │ ├── BaseBlockCipherSerializer.java │ │ ├── CipherSerializer.java │ │ ├── EncryptedMultipartSerializer.java │ │ ├── EncryptedMultipartUploaSerializationHelper.java │ │ ├── EncryptionStateSerializer.java │ │ ├── HmacSerializer.java │ │ ├── MantaClientSerializationException.java │ │ ├── MultipartUploadSerializer.java │ │ ├── PKCS11Serializer.java │ │ ├── ProviderSerializer.java │ │ ├── ReflectionUtils.java │ │ ├── SessionRefSerializer.java │ │ ├── SupportedCipherDetailsSerializer.java │ │ ├── UUIDSerializer.java │ │ └── package-info.java │ └── test │ ├── java │ └── com │ │ └── joyent │ │ └── manta │ │ └── serialization │ │ ├── CipherSerializerTest.java │ │ ├── EncryptedMultipartManagerSerializationTest.java │ │ ├── EncryptedMultipartUploadSerializationHelperTest.java │ │ ├── EncryptionStateSerializerTest.java │ │ └── HmacSerializerTest.java │ └── resources │ ├── logback-test.xml │ └── testng.xml ├── java-manta-client-unshaded ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ ├── joyent │ │ └── manta │ │ │ ├── client │ │ │ ├── FindForkJoinPoolFactory.java │ │ │ ├── MantaClient.java │ │ │ ├── MantaClientAgent.java │ │ │ ├── MantaDirectoryListingIterator.java │ │ │ ├── MantaMBeanable.java │ │ │ ├── MantaMetadata.java │ │ │ ├── MantaObject.java │ │ │ ├── MantaObjectConversionFunction.java │ │ │ ├── MantaObjectDepthComparator.java │ │ │ ├── MantaObjectInputStream.java │ │ │ ├── MantaObjectMapper.java │ │ │ ├── MantaObjectOutputStream.java │ │ │ ├── MantaObjectResponse.java │ │ │ ├── MantaSeekableByteChannel.java │ │ │ ├── MetricReporterSupplier.java │ │ │ ├── PruneEmptyParentDirectoryStrategy.java │ │ │ ├── RecursiveDirectoryCreationStrategy.java │ │ │ ├── StringIteratorHttpContent.java │ │ │ ├── UriSigner.java │ │ │ ├── crypto │ │ │ │ ├── AbstractAesCipherDetails.java │ │ │ │ ├── AesCbcCipherDetails.java │ │ │ │ ├── AesCipherDetailsFactory.java │ │ │ │ ├── AesCtrCipherDetails.java │ │ │ │ ├── AesGcmCipherDetails.java │ │ │ │ ├── ByteRangeConversion.java │ │ │ │ ├── EncryptedMetadataUtils.java │ │ │ │ ├── EncryptingEntity.java │ │ │ │ ├── EncryptingEntityHelper.java │ │ │ │ ├── EncryptingPartEntity.java │ │ │ │ ├── EncryptionContext.java │ │ │ │ ├── EncryptionType.java │ │ │ │ ├── ExternalSecurityProviderLoader.java │ │ │ │ ├── LocallyIllegalAesCipherDetails.java │ │ │ │ ├── MantaEncryptedObjectInputStream.java │ │ │ │ ├── SecretKeyUtils.java │ │ │ │ ├── SupportedCipherDetails.java │ │ │ │ ├── SupportedCiphersLookupMap.java │ │ │ │ ├── SupportedHmacsLookupMap.java │ │ │ │ └── package-info.java │ │ │ ├── jobs │ │ │ │ ├── MantaJob.java │ │ │ │ ├── MantaJobBuilder.java │ │ │ │ ├── MantaJobError.java │ │ │ │ ├── MantaJobPhase.java │ │ │ │ └── package-info.java │ │ │ ├── multipart │ │ │ │ ├── AbstractMultipartManager.java │ │ │ │ ├── AbstractMultipartUpload.java │ │ │ │ ├── CreateMPURequestBody.java │ │ │ │ ├── EncryptedMultipartManager.java │ │ │ │ ├── EncryptedMultipartUpload.java │ │ │ │ ├── EncryptedServerSideMultipartManager.java │ │ │ │ ├── EncryptionState.java │ │ │ │ ├── EncryptionStateRecorder.java │ │ │ │ ├── EncryptionStateSnapshot.java │ │ │ │ ├── MantaMultipartManager.java │ │ │ │ ├── MantaMultipartStatus.java │ │ │ │ ├── MantaMultipartUpload.java │ │ │ │ ├── MantaMultipartUploadPart.java │ │ │ │ ├── MantaMultipartUploadTuple.java │ │ │ │ ├── MultipartOutputStream.java │ │ │ │ ├── ServerSideMultipartManager.java │ │ │ │ ├── ServerSideMultipartUpload.java │ │ │ │ └── package-info.java │ │ │ └── package-info.java │ │ │ ├── config │ │ │ ├── AuthAwareConfigContext.java │ │ │ ├── BaseChainedConfigContext.java │ │ │ ├── ChainedConfigContext.java │ │ │ ├── ConfigContext.java │ │ │ ├── ConfigContextMBean.java │ │ │ ├── DefaultsConfigContext.java │ │ │ ├── EncryptionAuthenticationMode.java │ │ │ ├── EnvVarConfigContext.java │ │ │ ├── KeyPairFactory.java │ │ │ ├── MantaClientMetricConfiguration.java │ │ │ ├── MapConfigContext.java │ │ │ ├── MetricReporterMode.java │ │ │ ├── SettableConfigContext.java │ │ │ ├── StandardConfigContext.java │ │ │ ├── SystemSettingsConfigContext.java │ │ │ └── package-info.java │ │ │ ├── domain │ │ │ ├── Entity.java │ │ │ ├── ErrorDetail.java │ │ │ ├── ObjectType.java │ │ │ └── package-info.java │ │ │ ├── exception │ │ │ ├── ConfigurationException.java │ │ │ ├── HttpDownloadContinuationException.java │ │ │ ├── HttpDownloadContinuationIncompatibleRequestException.java │ │ │ ├── HttpDownloadContinuationUnexpectedResponseException.java │ │ │ ├── MantaAuthenticationException.java │ │ │ ├── MantaChecksumFailedException.java │ │ │ ├── MantaClientEncryptionCiphertextAuthenticationException.java │ │ │ ├── MantaClientEncryptionException.java │ │ │ ├── MantaClientException.java │ │ │ ├── MantaClientHttpResponseException.java │ │ │ ├── MantaEncryptionException.java │ │ │ ├── MantaErrorCode.java │ │ │ ├── MantaException.java │ │ │ ├── MantaIOException.java │ │ │ ├── MantaJobException.java │ │ │ ├── MantaMemoizationException.java │ │ │ ├── MantaMultipartException.java │ │ │ ├── MantaNoHttpResponseException.java │ │ │ ├── MantaObjectException.java │ │ │ ├── MantaReflectionException.java │ │ │ ├── MantaResourceCloseException.java │ │ │ ├── MantaUnexpectedObjectTypeException.java │ │ │ ├── OnCloseAggregateException.java │ │ │ ├── UnauthenticatableOperationException.java │ │ │ └── package-info.java │ │ │ ├── http │ │ │ ├── ApacheHttpGetResponseEntityContentContinuator.java │ │ │ ├── ApacheHttpHeaderUtils.java │ │ │ ├── ContentTypeLookup.java │ │ │ ├── DynamicHttpSignatureRequestInterceptor.java │ │ │ ├── EncryptionHttpHelper.java │ │ │ ├── HttpConnectionAware.java │ │ │ ├── HttpContextRetryCancellation.java │ │ │ ├── HttpDownloadContinuationMarker.java │ │ │ ├── HttpHelper.java │ │ │ ├── HttpRange.java │ │ │ ├── InstrumentedMantaHttpRequestExecutor.java │ │ │ ├── InstrumentedPoolingHttpClientConnectionManager.java │ │ │ ├── MantaApacheHttpClientContext.java │ │ │ ├── MantaConnectionContext.java │ │ │ ├── MantaConnectionFactory.java │ │ │ ├── MantaConnectionFactoryConfigurator.java │ │ │ ├── MantaContentTypes.java │ │ │ ├── MantaHttpHeaders.java │ │ │ ├── MantaHttpRequestExecutor.java │ │ │ ├── MantaHttpRequestFactory.java │ │ │ ├── MantaHttpRequestRetryHandler.java │ │ │ ├── MantaSSLConnectionSocketFactory.java │ │ │ ├── MantaServiceUnavailableRetryStrategy.java │ │ │ ├── PlaintextByteRangePosition.java │ │ │ ├── PoolStatsMBean.java │ │ │ ├── RequestIdInterceptor.java │ │ │ ├── RetryConfigAware.java │ │ │ ├── ShufflingDnsResolver.java │ │ │ ├── StandardHttpHelper.java │ │ │ ├── entity │ │ │ │ ├── DigestedEntity.java │ │ │ │ ├── EmbeddedHttpContent.java │ │ │ │ ├── ExposedByteArrayEntity.java │ │ │ │ ├── ExposedStringEntity.java │ │ │ │ ├── MantaInputStreamEntity.java │ │ │ │ ├── MemoryBackedEntity.java │ │ │ │ ├── NoContentEntity.java │ │ │ │ └── package-info.java │ │ │ └── package-info.java │ │ │ └── util │ │ │ ├── AutoContinuingInputStream.java │ │ │ ├── CipherCloner.java │ │ │ ├── Cloner.java │ │ │ ├── ConcurrentWeakIdentityHashMap.java │ │ │ ├── ContinuingInputStream.java │ │ │ ├── DigestCloner.java │ │ │ ├── HmacCloner.java │ │ │ ├── HmacOutputStream.java │ │ │ ├── InputStreamContinuator.java │ │ │ ├── LookupMap.java │ │ │ ├── MantaUtils.java │ │ │ ├── MantaVersion.java │ │ │ ├── MetricsAware.java │ │ │ ├── NotThreadSafe.java │ │ │ └── package-info.java │ │ └── twmacinta │ │ └── util │ │ ├── FastMD5Digest.java │ │ └── package-info.java │ └── test │ ├── java │ └── com │ │ ├── joyent │ │ └── manta │ │ │ ├── client │ │ │ ├── AuthAwareConfigContextTest.java │ │ │ ├── MantaClientAgentTest.java │ │ │ ├── MantaClientConnectionFailuresIT.java │ │ │ ├── MantaClientTest.java │ │ │ ├── MantaClientValidationTest.java │ │ │ ├── MantaDirectoryListingIteratorTest.java │ │ │ ├── MantaMetadataTest.java │ │ │ ├── MantaObjectDepthComparatorTest.java │ │ │ ├── MetricReporterSupplierTest.java │ │ │ ├── PruneEmptyParentDirectoryStrategyTest.java │ │ │ ├── crypto │ │ │ │ ├── AbstractCipherDetailsTest.java │ │ │ │ ├── AbstractMantaEncryptedObjectInputStreamTest.java │ │ │ │ ├── AesCbcCipherDetailsTest.java │ │ │ │ ├── AesCtrCipherDetailsTest.java │ │ │ │ ├── AesGcmCipherDetailsTest.java │ │ │ │ ├── ByteRangeConversionTest.java │ │ │ │ ├── EncryptedMetadataUtilsTest.java │ │ │ │ ├── EncryptingEntityTest.java │ │ │ │ ├── EncryptionTypeTest.java │ │ │ │ ├── ExternalSecurityProviderLoaderTest.java │ │ │ │ ├── IncompleteByteReadInputStream.java │ │ │ │ ├── LocallyIllegalAesCipherDetailsTest.java │ │ │ │ ├── MantaEncryptedObjectInputStreamAutoFailureRecoveryTest.java │ │ │ │ ├── MantaEncryptedObjectInputStreamTest.java │ │ │ │ ├── MultiCryptoProviderDecryptionTest.java │ │ │ │ ├── SecretKeyUtilsTest.java │ │ │ │ └── SupportedCiphersLookupMapTest.java │ │ │ ├── jobs │ │ │ │ ├── MantaJobPhaseTest.java │ │ │ │ └── MantaJobTest.java │ │ │ └── multipart │ │ │ │ ├── EncryptedMultipartManagerTest.java │ │ │ │ ├── EncryptingPartEntityTest.java │ │ │ │ ├── EncryptionStateRecorderTest.java │ │ │ │ ├── MultipartOutputStreamTest.java │ │ │ │ ├── ServerSideMultipartManagerTest.java │ │ │ │ ├── TestMultipartManager.java │ │ │ │ ├── TestMultipartManagerTest.java │ │ │ │ └── TestMultipartUpload.java │ │ │ ├── config │ │ │ ├── ChainedConfigContextTest.java │ │ │ ├── ChainedConfigKeyPathOriginTest.java │ │ │ ├── ConfigContextTest.java │ │ │ ├── MantaClientMetricConfigurationTest.java │ │ │ ├── SystemSettingsConfigContextTest.java │ │ │ ├── TestConfigContext.java │ │ │ └── TestConfigContextTest.java │ │ │ ├── exception │ │ │ ├── ConfigurationExceptionTest.java │ │ │ ├── MantaChecksumFailedExceptionTest.java │ │ │ ├── MantaClientHttpResponseExceptionTest.java │ │ │ ├── MantaErrorCodeTest.java │ │ │ ├── MantaExceptionTest.java │ │ │ ├── MantaIOExceptionTest.java │ │ │ └── OnCloseAggregateExceptionTest.java │ │ │ ├── http │ │ │ ├── ApacheHttpGetResponseEntityContentContinuatorTest.java │ │ │ ├── ApacheHttpHeaderUtilsTest.java │ │ │ ├── ApacheHttpTestUtils.java │ │ │ ├── ContentTypeLookupTest.java │ │ │ ├── EncryptedHttpHelperTest.java │ │ │ ├── FakeCloseableHttpClient.java │ │ │ ├── HttpDownloadContinuationMarkerTest.java │ │ │ ├── HttpRangeTest.java │ │ │ ├── InstrumentedMantaHttpRequestExecutorTest.java │ │ │ ├── InstrumentedPoolingHttpClientConnectionManagerTest.java │ │ │ ├── MantaConnectionFactoryConfiguratorTest.java │ │ │ ├── MantaConnectionFactoryTest.java │ │ │ ├── MantaHttpHeadersByteRangeTest.java │ │ │ ├── MantaHttpHeadersTest.java │ │ │ ├── MantaHttpRequestRetryHandlerTest.java │ │ │ ├── StandardHttpHelperTest.java │ │ │ └── entity │ │ │ │ ├── DigestedEntityTest.java │ │ │ │ └── ExposedStringEntityTest.java │ │ │ └── util │ │ │ ├── AutoContinuingInputStreamTest.java │ │ │ ├── CipherClonerTest.java │ │ │ ├── ContinuingInputStreamTest.java │ │ │ ├── FailingInputStream.java │ │ │ ├── FailingOutputStream.java │ │ │ ├── FileInputStreamContinuator.java │ │ │ ├── FileInputStreamContinuatorTest.java │ │ │ ├── HmacClonerTest.java │ │ │ ├── MantaUtilsTest.java │ │ │ ├── MantaVersionTest.java │ │ │ └── UnitTestConstants.java │ │ └── twmacinta │ │ └── util │ │ └── FastMD5DigestTest.java │ └── resources │ ├── logback-test.xml │ ├── test-data │ ├── chaucer.txt │ └── ciphertext │ │ ├── AES128-CBC-PKCS5Padding.ciphertext │ │ ├── AES128-CBC-PKCS5Padding.headers │ │ ├── AES128-CTR-NoPadding.ciphertext │ │ ├── AES128-CTR-NoPadding.headers │ │ ├── AES128-GCM-NoPadding.ciphertext │ │ ├── AES128-GCM-NoPadding.headers │ │ ├── AES192-CBC-PKCS5Padding.ciphertext │ │ ├── AES192-CBC-PKCS5Padding.headers │ │ ├── AES192-CTR-NoPadding.ciphertext │ │ ├── AES192-CTR-NoPadding.headers │ │ ├── AES192-GCM-NoPadding.ciphertext │ │ ├── AES192-GCM-NoPadding.headers │ │ ├── AES256-CBC-PKCS5Padding.ciphertext │ │ ├── AES256-CBC-PKCS5Padding.headers │ │ ├── AES256-CTR-NoPadding.ciphertext │ │ ├── AES256-CTR-NoPadding.headers │ │ ├── AES256-GCM-NoPadding.ciphertext │ │ └── AES256-GCM-NoPadding.headers │ └── testng.xml ├── java-manta-client └── pom.xml ├── java-manta-examples ├── pom.xml └── src │ └── main │ └── java │ ├── ClientEncryptionDownloadException.java │ ├── ClientEncryptionMetadata.java │ ├── ClientEncryptionRangeDownload.java │ ├── ClientEncryptionServerMultipart.java │ ├── DynamicAuthentication.java │ ├── JobsWithMantaClient.java │ ├── JobsWithMantaJobBuilder.java │ ├── ServerMultipart.java │ ├── SimpleClient.java │ └── SimpleClientEncryption.java ├── java-manta-it ├── pom.xml └── src │ ├── .gitignore │ └── test │ ├── java │ └── com │ │ └── joyent │ │ ├── manta │ │ ├── client │ │ │ ├── MantaClientAuthenticationChangeIT.java │ │ │ ├── MantaClientAuthenticationIT.java │ │ │ ├── MantaClientDirectoriesIT.java │ │ │ ├── MantaClientErrorIT.java │ │ │ ├── MantaClientFindIT.java │ │ │ ├── MantaClientIT.java │ │ │ ├── MantaClientMetadataIT.java │ │ │ ├── MantaClientPutIT.java │ │ │ ├── MantaClientRangeIT.java │ │ │ ├── MantaClientSeekableByteChannelIT.java │ │ │ ├── MantaClientSigningIT.java │ │ │ ├── MantaClientSnapLinksIT.java │ │ │ ├── MantaDirectoryListingIteratorIT.java │ │ │ ├── MantaObjectOutputStreamIT.java │ │ │ ├── TestSuiteSetup.java │ │ │ ├── jobs │ │ │ │ ├── MantaClientJobIT.java │ │ │ │ └── MantaJobBuilderIT.java │ │ │ └── multipart │ │ │ │ ├── EncryptedServerSideMultipartManagerIT.java │ │ │ │ ├── EncryptedServerSideMultipartManagerSerializationIT.java │ │ │ │ └── ServerSideMultipartManagerIT.java │ │ ├── config │ │ │ └── IntegrationTestConfigContext.java │ │ └── http │ │ │ ├── ApacheHttpGetResponseEntityContentContinuatorIT.java │ │ │ ├── MantaHttpHeadersIT.java │ │ │ └── TCPSocketConnectionTimeoutIT.java │ │ └── test │ │ └── util │ │ ├── FailingInputStream.java │ │ ├── FailingInputStreamTest.java │ │ ├── MantaAssert.java │ │ ├── MantaFunction.java │ │ ├── MantaPathSuiteListener.java │ │ ├── RandomInputStream.java │ │ ├── RandomInputStreamTest.java │ │ ├── SpuriousIOException.java │ │ ├── TestListingInterceptor.java │ │ └── ThreeTriesRetryAnalyzer.java │ └── resources │ ├── Master-Yoda.jpg │ ├── logback-test.xml │ └── testng-it.xml ├── license-history.txt ├── pom.xml └── suppressions.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### Intellij ### 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 5 | 6 | *.iml 7 | 8 | ## Directory-based project format: 9 | .idea/ 10 | # if you remove the above rule, at least ignore the following: 11 | 12 | # User-specific stuff: 13 | # .idea/workspace.xml 14 | # .idea/tasks.xml 15 | # .idea/dictionaries 16 | 17 | # Sensitive or high-churn files: 18 | # .idea/dataSources.ids 19 | # .idea/dataSources.xml 20 | # .idea/sqlDataSources.xml 21 | # .idea/dynamic.xml 22 | # .idea/uiDesigner.xml 23 | 24 | # Gradle: 25 | # .idea/gradle.xml 26 | # .idea/libraries 27 | 28 | # Mongo Explorer plugin: 29 | # .idea/mongoSettings.xml 30 | 31 | ## File-based project format: 32 | *.ipr 33 | *.iws 34 | 35 | ## Plugin-specific files: 36 | 37 | # IntelliJ 38 | out/ 39 | 40 | # mpeltonen/sbt-idea plugin 41 | .idea_modules/ 42 | 43 | # JIRA plugin 44 | atlassian-ide-plugin.xml 45 | 46 | # Crashlytics plugin (for Android Studio and IntelliJ) 47 | com_crashlytics_export_strings.xml 48 | crashlytics.properties 49 | crashlytics-build.properties 50 | 51 | 52 | ### Eclipse ### 53 | *.pydevproject 54 | .metadata 55 | .gradle 56 | bin/ 57 | tmp/ 58 | *.tmp 59 | *.bak 60 | *.swp 61 | *~.nib 62 | local.properties 63 | .settings/ 64 | .loadpath 65 | .project 66 | .classpath 67 | .checkstyle 68 | workbench.xmi 69 | 70 | ### Netbeans ### 71 | nbactions.xml 72 | 73 | # External tool builders 74 | .externalToolBuilders/ 75 | 76 | # Locally stored "Eclipse launch configurations" 77 | *.launch 78 | 79 | # CDT-specific 80 | .cproject 81 | 82 | # PDT-specific 83 | .buildpath 84 | 85 | # sbteclipse plugin 86 | .target 87 | 88 | # TeXlipse plugin 89 | .texlipse 90 | 91 | 92 | ### Maven ### 93 | target/ 94 | pom.xml.tag 95 | pom.xml.releaseBackup 96 | pom.xml.versionsBackup 97 | pom.xml.next 98 | release.properties 99 | dependency-reduced-pom.xml 100 | 101 | **/test-output 102 | 103 | ### macOS ### 104 | .DS_Store 105 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We love pull requests from everyone. 4 | 5 | Fork, then clone the repo: 6 | 7 | git clone git@github.com:your-username/joyent/java-manta.git 8 | 9 | For running integration tests, you will need an account on a Manta system this could 10 | be the [Joyent Public Cloud](https://www.joyent.com/public-cloud) or an 11 | on-premise Manta installation. 12 | 13 | Set up your machine: 14 | 15 | You will need to set the following environment variables (or their aliases): 16 | MANTA_URL, MANTA_USER, MANTA_KEY_ID, MANTA_KEY_PATH 17 | 18 | It may be useful to install the [node.js triton utility](https://www.npmjs.com/package/manta) 19 | to verify that you can connect to Manta before running the tests: 20 | 21 | npm install -g manta 22 | 23 | Make sure all tests including the integration tests pass: 24 | 25 | mvn verify 26 | 27 | Make your change. Add tests for your change. Make sure that all tests and style 28 | checks pass: 29 | 30 | mvn checkstyle:checkstyle -Dcheckstyle.skip=false verify 31 | 32 | Add your changes to the CHANGELOG.md and commit. 33 | 34 | Push to your fork and [submit a pull request][pr]. 35 | 36 | [pr]: https://github.com/joyent/java-manta/compare/ 37 | 38 | At this point you're waiting on us. We like to at least comment on pull requests 39 | within three business days (and, typically, one business day). We may suggest 40 | some changes or improvements or alternatives. 41 | 42 | Some things that will increase the chance that your pull request is accepted: 43 | 44 | * Filing a github issue describing the improvement or the bug before you start work. 45 | * Write tests. 46 | * Follow the style defined in (checkstyle.xml)[checkstyle.xml]. 47 | * Write a good commit message. 48 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | The product includes software from the ehcache3 project 2 | under the Apache License 2.0 (see: com.joyent.manta.util.ConcurrentWeakIdentityHashMap). 3 | 4 | The product includes software from the Apache HTTPClient project 5 | under the Apache License 2.0 (see: com.joyent.manta.util.NotThreadSafe). -------------------------------------------------------------------------------- /java-manta-benchmark/src/main/java/com/joyent/manta/benchmark/RandomInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.benchmark; 9 | 10 | import org.apache.commons.lang3.RandomUtils; 11 | 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.util.concurrent.atomic.AtomicLong; 15 | 16 | /** 17 | * {@link InputStream} implementation that generates random data. 18 | * 19 | * @author Elijah Zupancic 20 | */ 21 | public class RandomInputStream extends InputStream { 22 | /** 23 | * End of file magic number. 24 | */ 25 | private static final int EOF = -1; 26 | 27 | /** 28 | * Maximum number of bytes to generate. 29 | */ 30 | private final long maximumBytes; 31 | 32 | /** 33 | * Current generated byte count. 34 | */ 35 | private AtomicLong count = new AtomicLong(0L); 36 | 37 | /** 38 | * Creates a new instance. 39 | * @param maximumBytes maximum number of random bytes in stream 40 | */ 41 | public RandomInputStream(final long maximumBytes) { 42 | this.maximumBytes = maximumBytes; 43 | } 44 | 45 | @Override 46 | public int read() throws IOException { 47 | if (count.getAndIncrement() >= maximumBytes) { 48 | return EOF; 49 | } 50 | 51 | return RandomUtils.nextInt(0, Integer.MAX_VALUE); 52 | } 53 | 54 | @Override 55 | public int read(final byte[] b, final int off, final int len) throws IOException { 56 | if (count.get() >= maximumBytes) { 57 | return EOF; 58 | } 59 | 60 | final int bytesToRead; 61 | 62 | if (maximumBytes - count.get() >= len) { 63 | bytesToRead = len; 64 | } else { 65 | bytesToRead = (int)(maximumBytes - count.get()); 66 | } 67 | 68 | count.addAndGet(bytesToRead); 69 | 70 | final byte[] randomBytes = RandomUtils.nextBytes(bytesToRead); 71 | 72 | System.arraycopy(randomBytes, 0, b, off, bytesToRead); 73 | 74 | return bytesToRead; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /java-manta-benchmark/src/main/java/com/joyent/manta/benchmark/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing classes used for benchmarking the Manta client. 11 | * @author Elijah Zupancic 12 | */ 13 | package com.joyent.manta.benchmark; 14 | -------------------------------------------------------------------------------- /java-manta-benchmark/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | 7 | 9 | 10 | [%thread] %-5level %logger - %msg%n 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /java-manta-cli/src/main/java/com/joyent/manta/cli/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing classes used for CLI interaction with the SDK. 11 | * 12 | * @author Elijah Zupancic 13 | * @since 3.0.0 14 | */ 15 | package com.joyent.manta.cli; 16 | -------------------------------------------------------------------------------- /java-manta-cli/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 13 | 14 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 15 | 16 | System.err 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/EncryptedMultipartSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.serialization; 9 | 10 | import com.esotericsoftware.kryo.Kryo; 11 | import com.esotericsoftware.kryo.serializers.FieldSerializer; 12 | import com.joyent.manta.client.multipart.AbstractMultipartUpload; 13 | import com.joyent.manta.client.multipart.EncryptedMultipartUpload; 14 | import com.joyent.manta.client.multipart.EncryptionState; 15 | 16 | import javax.crypto.SecretKey; 17 | 18 | /** 19 | * Kryo serializer for serializing {@link EncryptedMultipartUpload} 20 | * instances. 21 | * 22 | * @author Elijah Zupancic 23 | * @since 3.0.0 24 | * 25 | * @param underlying {@link AbstractMultipartUpload} generic type of serialized class 26 | */ 27 | public class EncryptedMultipartSerializer 28 | extends FieldSerializer> { 29 | 30 | /** 31 | * Secret key to inject upon deserialization. 32 | */ 33 | private SecretKey secretKey; 34 | 35 | /** 36 | * Class of underlying {@link AbstractMultipartUpload} generic type of 37 | * serialized class. 38 | */ 39 | private Class wrappedType; 40 | 41 | /** 42 | * Creates a new serializer instance. 43 | * 44 | * @param kryo Kryo instance 45 | * @param type type of instance to serialize 46 | * @param wrappedType type of wrapped type of serialized class 47 | * @param secretKey secret key to inject on deserialize 48 | */ 49 | public EncryptedMultipartSerializer(final Kryo kryo, 50 | final Class type, 51 | final Class wrappedType, 52 | final SecretKey secretKey) { 53 | super(kryo, type); 54 | this.wrappedType = wrappedType; 55 | this.secretKey = secretKey; 56 | 57 | registerClasses(kryo); 58 | } 59 | 60 | /** 61 | * Registers the classes needed for serialization with Kryo. 62 | * 63 | * @param kryo Kryo instance 64 | */ 65 | private void registerClasses(final Kryo kryo) { 66 | kryo.register(EncryptionState.class, new EncryptionStateSerializer(kryo, secretKey)); 67 | kryo.register(wrappedType, new MultipartUploadSerializer(kryo, wrappedType)); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/MantaClientSerializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.serialization; 9 | 10 | import com.joyent.manta.exception.MantaClientException; 11 | 12 | /** 13 | * Exception class for errors relating to serialization. 14 | * 15 | * @author Elijah Zupancic 16 | * @since 3.0.0 17 | */ 18 | public class MantaClientSerializationException extends MantaClientException { 19 | private static final long serialVersionUID = 2881593409681385799L; 20 | 21 | /** 22 | * Create an empty exception. 23 | */ 24 | public MantaClientSerializationException() { 25 | } 26 | 27 | /** 28 | * @param message The error message. 29 | */ 30 | public MantaClientSerializationException(final String message) { 31 | super(message); 32 | } 33 | 34 | /** 35 | * @param cause The cause of the exception. 36 | */ 37 | public MantaClientSerializationException(final Throwable cause) { 38 | super(cause); 39 | } 40 | 41 | /** 42 | * @param message The error message. 43 | * @param cause The cause. 44 | */ 45 | public MantaClientSerializationException(final String message, 46 | final Throwable cause) { 47 | super(message, cause); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/MultipartUploadSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.serialization; 9 | 10 | import com.esotericsoftware.kryo.Kryo; 11 | import com.esotericsoftware.kryo.serializers.FieldSerializer; 12 | import com.joyent.manta.client.multipart.AbstractMultipartUpload; 13 | 14 | import java.util.UUID; 15 | 16 | /** 17 | * Kryo serializer for instances that extend {@link AbstractMultipartUpload}. 18 | * 19 | * @author Elijah Zupancic 20 | * @since 3.0.0 21 | * 22 | * @param type to serialize 23 | */ 24 | public class MultipartUploadSerializer extends FieldSerializer { 25 | /** 26 | * Creates new serializer instance. 27 | * @param kryo Kryo instance 28 | * @param type type of instance to serialize 29 | */ 30 | public MultipartUploadSerializer(final Kryo kryo, final Class type) { 31 | super(kryo, type); 32 | registerClasses(kryo); 33 | } 34 | 35 | /** 36 | * Registers the classes needed for serialization with Kryo. 37 | * 38 | * @param kryo Kryo instance 39 | */ 40 | private void registerClasses(final Kryo kryo) { 41 | kryo.register(UUID.class, new UUIDSerializer()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/PKCS11Serializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.serialization; 9 | 10 | import com.esotericsoftware.kryo.Kryo; 11 | import com.esotericsoftware.kryo.io.Input; 12 | import com.esotericsoftware.kryo.io.Output; 13 | import sun.security.pkcs11.wrapper.PKCS11; 14 | import sun.security.pkcs11.wrapper.PKCS11Exception; 15 | 16 | import java.io.IOException; 17 | import java.lang.reflect.Field; 18 | 19 | /** 20 | * Kryo serializer class that serializes {@link PKCS11} instances. 21 | * 22 | * @author Elijah Zupancic 23 | * @since 3.0.0 24 | */ 25 | public class PKCS11Serializer extends AbstractManualSerializer { 26 | /** 27 | * Name of field that identifies the PKCS11 module. 28 | */ 29 | private static final Field MODULE_PATH_FIELD = ReflectionUtils 30 | .getField(PKCS11.class, "pkcs11ModulePath"); 31 | 32 | /** 33 | * Creates a new serializer instance. 34 | */ 35 | public PKCS11Serializer() { 36 | super(PKCS11.class, false, true); 37 | } 38 | 39 | @Override 40 | public void write(final Kryo kryo, final Output output, final PKCS11 object) { 41 | Object modulePath = ReflectionUtils.readField(MODULE_PATH_FIELD, 42 | object); 43 | output.writeString(modulePath.toString()); 44 | } 45 | 46 | @Override 47 | public PKCS11 read(final Kryo kryo, final Input input, final Class type) { 48 | String modulePath = input.readString(); 49 | 50 | try { 51 | return PKCS11.getInstance(modulePath, "C_GetFunctionList", null, false); 52 | } catch (IOException | PKCS11Exception e) { 53 | throw new MantaClientSerializationException( 54 | "Unable to instantiate PKC11 class", e); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/ProviderSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.serialization; 9 | 10 | import com.esotericsoftware.kryo.Kryo; 11 | import com.esotericsoftware.kryo.Serializer; 12 | import com.esotericsoftware.kryo.io.Input; 13 | import com.esotericsoftware.kryo.io.Output; 14 | 15 | import java.security.Provider; 16 | import java.security.Security; 17 | 18 | /** 19 | * Serializer class that writes out the name of a {@link Provider} without 20 | * writing its state. 21 | * 22 | * @author Elijah Zupancic 23 | * @since 3.0.0 24 | */ 25 | public class ProviderSerializer extends Serializer { 26 | /** 27 | * Creates a new instance. 28 | */ 29 | public ProviderSerializer() { 30 | super(false, true); 31 | } 32 | 33 | @Override 34 | public void write(final Kryo kryo, final Output output, final Provider object) { 35 | final String name = object.getName(); 36 | output.writeString(name); 37 | } 38 | 39 | @Override 40 | public Provider read(final Kryo kryo, final Input input, final Class type) { 41 | final String name = input.readString(); 42 | return Security.getProvider(name); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/SupportedCipherDetailsSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.serialization; 9 | 10 | import com.esotericsoftware.kryo.Kryo; 11 | import com.esotericsoftware.kryo.Serializer; 12 | import com.esotericsoftware.kryo.io.Input; 13 | import com.esotericsoftware.kryo.io.Output; 14 | import com.joyent.manta.client.crypto.SupportedCipherDetails; 15 | import com.joyent.manta.client.crypto.SupportedCiphersLookupMap; 16 | 17 | /** 18 | * Serializer class for {@link SupportedCipherDetails} implementations 19 | * that only serializes the name of the cipher id. Deserialization is done 20 | * by looking up the id against the values in {@link SupportedCiphersLookupMap}. 21 | * 22 | * @author Elijah Zupancic 23 | * @since 3.0.0 24 | */ 25 | public class SupportedCipherDetailsSerializer extends Serializer { 26 | /** 27 | * Creates a new serializer instance. 28 | */ 29 | public SupportedCipherDetailsSerializer() { 30 | super(false); 31 | } 32 | 33 | @Override 34 | public void write(final Kryo kryo, 35 | final Output output, 36 | final SupportedCipherDetails object) { 37 | output.writeString(object.getCipherId()); 38 | } 39 | 40 | @Override 41 | public SupportedCipherDetails read(final Kryo kryo, 42 | final Input input, 43 | final Class type) { 44 | final String cipherId = input.readString(); 45 | return SupportedCiphersLookupMap.INSTANCE.get(cipherId); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/UUIDSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.serialization; 9 | 10 | import com.esotericsoftware.kryo.Kryo; 11 | import com.esotericsoftware.kryo.Serializer; 12 | import com.esotericsoftware.kryo.io.Input; 13 | import com.esotericsoftware.kryo.io.Output; 14 | 15 | import java.util.UUID; 16 | 17 | /** 18 | * Kryo serializer class that serializes {@link UUID} instances 19 | * as two longs. 20 | * 21 | * @author Elijah Zupancic 22 | * @since 3.0.0 23 | */ 24 | public class UUIDSerializer extends Serializer { 25 | /** 26 | * Creates a new serializer instance. 27 | */ 28 | public UUIDSerializer() { 29 | super(false); 30 | } 31 | 32 | @Override 33 | public void write(final Kryo kryo, final Output output, final UUID object) { 34 | output.writeVarLong(object.getMostSignificantBits(), false); 35 | output.writeVarLong(object.getLeastSignificantBits(), false); 36 | 37 | output.flush(); 38 | } 39 | 40 | @Override 41 | public UUID read(final Kryo kryo, final Input input, final Class type) { 42 | final long mostSignificantBits = input.readVarLong(false); 43 | final long leastSignificantBits = input.readVarLong(false); 44 | 45 | return new UUID(mostSignificantBits, leastSignificantBits); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/main/java/com/joyent/manta/serialization/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing Kryo compatible serialization classes. 11 | * 12 | * @author Elijah Zupancic 13 | * @since 3.0.0 14 | */ 15 | package com.joyent.manta.serialization; 16 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | [%thread] %-5level %logger - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /java-manta-client-kryo-serialization/src/test/resources/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/MantaMBeanable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client; 9 | 10 | import javax.management.DynamicMBean; 11 | 12 | /** 13 | * Interface for objects that can make themselves available as MBeans. 14 | * 15 | * @author Tomas Celaya 16 | * @since 3.1.7 17 | */ 18 | public interface MantaMBeanable { 19 | 20 | /** 21 | * Provide an MBean that represents this object for registration in JMX. 22 | * 23 | * @return The {@link DynamicMBean} that represents {@code this} 24 | */ 25 | DynamicMBean toMBean(); 26 | } 27 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/MantaObjectDepthComparator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client; 9 | 10 | import org.apache.commons.lang3.StringUtils; 11 | 12 | import java.util.Comparator; 13 | 14 | import static com.joyent.manta.client.MantaClient.SEPARATOR; 15 | 16 | /** 17 | * {@link Comparator} implementation that sorts {@link MantaObject} instances 18 | * by file first, then directory depth (deepest first). 19 | * 20 | * @author Elijah Zupancic 21 | * @since 3.1.7 22 | */ 23 | public final class MantaObjectDepthComparator implements Comparator { 24 | /** 25 | * Singleton instance of comparator. 26 | */ 27 | public static final MantaObjectDepthComparator INSTANCE = new MantaObjectDepthComparator(); 28 | 29 | /** 30 | * Creates a new comparator instance. 31 | */ 32 | private MantaObjectDepthComparator() { 33 | } 34 | 35 | @Override 36 | public int compare(final MantaObject o1, final MantaObject o2) { 37 | final int depthComparison = comparePathDepth(o1, o2); 38 | 39 | if (depthComparison == 0) { 40 | if (!o1.isDirectory() == !o2.isDirectory()) { 41 | return 0; 42 | } else if (!o1.isDirectory()) { 43 | return -1; 44 | } else { 45 | return 1; 46 | } 47 | } 48 | 49 | return depthComparison; 50 | } 51 | 52 | /** 53 | * Sorts two objects showing the deepest objects first. 54 | * 55 | * @param o1 the first object to be compared. 56 | * @param o2 the second object to be compared. 57 | * @return a negative integer, zero, or a positive integer as the 58 | * first argument is less than, equal to, or greater than the 59 | * second. 60 | */ 61 | private static int comparePathDepth(final MantaObject o1, final MantaObject o2) { 62 | final int o1Depth = StringUtils.countMatches(o1.getPath(), SEPARATOR); 63 | final int o2Depth = StringUtils.countMatches(o2.getPath(), SEPARATOR); 64 | // Note: reversed order - bigger values should come first 65 | return Integer.compare(o2Depth, o1Depth); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/MantaObjectMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client; 9 | 10 | import com.fasterxml.jackson.annotation.JsonInclude; 11 | import com.fasterxml.jackson.databind.DeserializationConfig; 12 | import com.fasterxml.jackson.databind.DeserializationFeature; 13 | import com.fasterxml.jackson.databind.ObjectMapper; 14 | import com.fasterxml.jackson.databind.SerializationConfig; 15 | import com.fasterxml.jackson.databind.node.JsonNodeFactory; 16 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 17 | 18 | /** 19 | * Provider class of {@link ObjectMapper} that is configured for use with 20 | * the Manta SDK. 21 | * 22 | * @author Elijah Zupancic 23 | */ 24 | public class MantaObjectMapper extends ObjectMapper { 25 | private static final long serialVersionUID = -54543439989941209L; 26 | 27 | /** 28 | * Jackson data binding mapper instance. 29 | */ 30 | public static final ObjectMapper INSTANCE = new MantaObjectMapper(); 31 | 32 | /** 33 | * JSON node factory instance. 34 | */ 35 | public static final JsonNodeFactory NODE_FACTORY_INSTANCE = 36 | new JsonNodeFactory(false); 37 | 38 | /** 39 | * Creates a configured instance of {@link ObjectMapper}. 40 | */ 41 | public MantaObjectMapper() { 42 | registerModule(new JavaTimeModule()); 43 | 44 | DeserializationConfig deserializationConfig = getDeserializationConfig() 45 | .without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) 46 | .without(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES); 47 | setConfig(deserializationConfig); 48 | 49 | SerializationConfig serializationConfig = getSerializationConfig(); 50 | setConfig(serializationConfig); 51 | 52 | setSerializationInclusion(JsonInclude.Include.NON_NULL); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/crypto/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing classes related to client-side encryption of Manta objects. 11 | * 12 | * @author Elijah Zupancic 13 | * @author Elijah Zupancic 14 | */ 15 | package com.joyent.manta.client.crypto; 16 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/jobs/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing all classes used for interacting with Manta jobs. 11 | * 12 | * @author Elijah Zupancic 13 | * @since 3.0.0 14 | */ 15 | package com.joyent.manta.client.jobs; 16 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/multipart/AbstractMultipartUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import org.apache.commons.lang3.builder.ToStringBuilder; 11 | 12 | import java.util.Objects; 13 | import java.util.UUID; 14 | 15 | /** 16 | * Base implementation of a multipart upload state object. 17 | * 18 | * @author Elijah Zupancic 19 | * @since 3.0.0 20 | */ 21 | public abstract class AbstractMultipartUpload implements MantaMultipartUpload { 22 | 23 | /** 24 | * Transaction ID for multipart upload. 25 | */ 26 | private UUID id; 27 | 28 | /** 29 | * Path to final object being uploaded to Manta. 30 | */ 31 | private String path; 32 | 33 | /** 34 | * Protected constructor for serialization purposes. 35 | */ 36 | protected AbstractMultipartUpload() { 37 | } 38 | 39 | /** 40 | * Creates a new instance. 41 | * 42 | * @param uploadId Transaction ID for multipart upload 43 | * @param path Path to final object being uploaded to Manta 44 | */ 45 | public AbstractMultipartUpload(final UUID uploadId, final String path) { 46 | this.id = uploadId; 47 | this.path = path; 48 | } 49 | 50 | @Override 51 | public boolean equals(final Object o) { 52 | if (this == o) { 53 | return true; 54 | } 55 | if (!(o instanceof AbstractMultipartUpload)) { 56 | return false; 57 | } 58 | 59 | final MantaMultipartUpload that = (MantaMultipartUpload) o; 60 | return Objects.equals(id, that.getId()) 61 | && Objects.equals(path, that.getPath()); 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return Objects.hash(id, path); 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return new ToStringBuilder(this) 72 | .append("id", id) 73 | .append("path", path) 74 | .toString(); 75 | } 76 | 77 | @Override 78 | public int compare(final MantaMultipartUpload o1, final MantaMultipartUpload o2) { 79 | return o1.getPath().compareTo(o2.getPath()); 80 | } 81 | 82 | @Override 83 | public UUID getId() { 84 | return id; 85 | } 86 | 87 | @Override 88 | public String getPath() { 89 | return path; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/multipart/EncryptedServerSideMultipartManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import com.joyent.manta.client.MantaClient; 11 | 12 | /** 13 | * Convenience class that implements the generic interface for an encrypted 14 | * server side multipart manager and creates the underlying wrapped instance 15 | * so that the API consumer doesn't have to wrangle with so many generics. 16 | * 17 | * @author Elijah Zupancic 18 | * @since 3.0.0 19 | */ 20 | public class EncryptedServerSideMultipartManager 21 | extends EncryptedMultipartManager { 22 | /** 23 | * Creates a new encrypted multipart upload manager that is backed by 24 | * a server-side supported manager. 25 | * 26 | * @param mantaClient manta client use for MPU operations 27 | */ 28 | public EncryptedServerSideMultipartManager(final MantaClient mantaClient) { 29 | super(mantaClient, new ServerSideMultipartManager(mantaClient)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/multipart/MantaMultipartStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | * Status enum that indicates the current state of a Manta multipart upload. 14 | * 15 | * @author Elijah Zupancic 16 | * @since 2.5.0 17 | */ 18 | public enum MantaMultipartStatus implements Serializable { 19 | /** Multipart upload is in a unknown state (not yet started is possible). */ 20 | UNKNOWN, 21 | /** Multipart upload was created and is still in progress. */ 22 | CREATED, 23 | /** Multipart upload is in the process of being finished and written to disk. */ 24 | COMMITTING, 25 | /** Multipart upload is in the process of being aborted. */ 26 | ABORTING, 27 | /** Multipart upload has already finished and the final object was written. */ 28 | COMPLETED, 29 | /** Multipart upload has been aborted. */ 30 | ABORTED; 31 | 32 | private static final long serialVersionUID = 2798516320088229874L; 33 | } 34 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/multipart/MantaMultipartUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import java.util.Comparator; 11 | import java.util.UUID; 12 | 13 | /** 14 | * Interface representing a multipart upload in progress. 15 | * 16 | * @author Elijah Zupancic 17 | * @since 2.5.0 18 | */ 19 | public interface MantaMultipartUpload extends Comparator { 20 | /** 21 | * @return upload id for the entire multipart upload operation 22 | */ 23 | UUID getId(); 24 | 25 | /** 26 | * @return path to the final object 27 | */ 28 | String getPath(); 29 | } 30 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/multipart/MantaMultipartUploadPart.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import com.joyent.manta.client.MantaClient; 11 | import com.joyent.manta.client.MantaObject; 12 | import com.joyent.manta.util.MantaUtils; 13 | import org.apache.commons.lang3.builder.ToStringBuilder; 14 | 15 | import java.io.Serializable; 16 | 17 | 18 | /** 19 | * A single part of a multipart upload. 20 | * 21 | * @author Elijah Zupancic 22 | * @since 2.5.0 23 | */ 24 | public class MantaMultipartUploadPart extends MantaMultipartUploadTuple 25 | implements Serializable { 26 | private static final long serialVersionUID = -738331736064518314L; 27 | 28 | /** 29 | * Remote path on Manta for the part's file. 30 | */ 31 | private final String objectPath; 32 | 33 | /** 34 | * Creates a new instance based on explicitly defined parameters. 35 | * 36 | * @param partNumber Non-zero positive integer representing the relative position of the part 37 | * @param objectPath Remote path on Manta for the part's file 38 | * @param etag Etag value of the part 39 | */ 40 | public MantaMultipartUploadPart(final int partNumber, final String objectPath, 41 | final String etag) { 42 | 43 | super(partNumber, etag); 44 | this.objectPath = objectPath; 45 | } 46 | 47 | /** 48 | * Creates a new instance based on a response from {@link MantaClient}. 49 | * 50 | * @param object response object from returned from {@link MantaClient} 51 | */ 52 | public MantaMultipartUploadPart(final MantaObject object) { 53 | super(Integer.parseInt(MantaUtils.lastItemInPath(object.getPath())), 54 | object.getEtag()); 55 | 56 | this.objectPath = object.getPath(); 57 | } 58 | 59 | protected String getObjectPath() { 60 | return objectPath; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return new ToStringBuilder(this) 66 | .append("partNumber", getPartNumber()) 67 | .append("objectPath", getObjectPath()) 68 | .append("etag", getEtag()) 69 | .toString(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/multipart/ServerSideMultipartUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2019, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import org.apache.commons.lang3.builder.ToStringBuilder; 11 | 12 | import java.util.Objects; 13 | import java.util.UUID; 14 | 15 | /** 16 | * Multipart upload state object used for server-side MPU. 17 | * 18 | * @author Elijah Zupancic 19 | * @since 3.0.0 20 | */ 21 | public class ServerSideMultipartUpload extends AbstractMultipartUpload { 22 | /** 23 | * Directory containing the multipart upload parts. 24 | */ 25 | private String partsDirectory; 26 | 27 | /** 28 | * Private constructor for serialization purposes. 29 | */ 30 | private ServerSideMultipartUpload() { 31 | super(); 32 | } 33 | 34 | /** 35 | * Creates a new instance with a parts directory in addition to the 36 | * parameters used in the super class. 37 | * 38 | * @param uploadId Transaction ID for multipart upload 39 | * @param path Path to final object being uploaded to Manta 40 | * @param partsDirectory path to the multipart parts directory on manta for this upload 41 | */ 42 | public ServerSideMultipartUpload(final UUID uploadId, final String path, 43 | final String partsDirectory) { 44 | super(uploadId, path); 45 | this.partsDirectory = partsDirectory; 46 | } 47 | 48 | public String getPartsDirectory() { 49 | return partsDirectory; 50 | } 51 | 52 | @Override 53 | public boolean equals(final Object o) { 54 | if (this == o) { 55 | return true; 56 | } 57 | if (!(o instanceof ServerSideMultipartUpload)) { 58 | return false; 59 | } 60 | if (!super.equals(o)) { 61 | return false; 62 | } 63 | 64 | final ServerSideMultipartUpload that = (ServerSideMultipartUpload)o; 65 | return Objects.equals(partsDirectory, that.partsDirectory); 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return Objects.hash(super.hashCode(), partsDirectory); 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return new ToStringBuilder(this) 76 | .append("id", getId()) 77 | .append("path", getPath()) 78 | .append("partsDirectory", partsDirectory) 79 | .toString(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/multipart/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | *

Package containing all of the classes used as part of the Manta Multipart 11 | * upload API.

12 | * 13 | *

This package contains two very different implementations for doing 14 | * multipart upload:

15 | *
    16 | *
  • Jobs-based multipart - this performs multipart uploads using Manta 17 | * jobs to concatenate the uploaded parts. This is a legacy 18 | * implementation for Manta deployments that do not yet support 19 | * server-side natively supported multipart uploads.
  • 20 | *
  • Server side multipart - this performs multipart uploads using Manta's 21 | * native support for multipart uploads. If the Manta deployment that 22 | * you are connecting to supports this mode, then you should use 23 | * this implementation.
  • 24 | *
25 | * 26 | *

There are also abstract classes and interfaces that allow you to 27 | * implement your own API compatible implementation to use for testing. 28 | * Additionally, there are encryption implementations that allow for 29 | * the wrapping of a backing multipart implementation and seamlessly 30 | * encrypting the uploaded parts.

31 | * 32 | * @author Elijah Zupancic 33 | * @since 2.5.0 34 | */ 35 | package com.joyent.manta.client.multipart; 36 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/client/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Manta Java client package. 11 | * 12 | * @author Yunong Xiao 13 | */ 14 | package com.joyent.manta.client; 15 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/config/ChainedConfigContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.config; 9 | 10 | /** 11 | * Implementation of {@link ConfigContext} that links together multiple contexts. 12 | * This allows you to create tiers of configuration in which certain configuration 13 | * contexts are given priority over others. 14 | * 15 | * @author Elijah Zupancic 16 | */ 17 | public class ChainedConfigContext extends BaseChainedConfigContext { 18 | /** 19 | * Creates a new {@link ConfigContext} implementation that allows you 20 | * to chain together multiple configuration contexts that progressively 21 | * overwrite the values of the previous contexts (but never overwriting 22 | * with null). 23 | * 24 | * @param contexts N number of configuration contexts 25 | */ 26 | public ChainedConfigContext(final ConfigContext... contexts) { 27 | for (ConfigContext c : contexts) { 28 | overwriteWithContext(c); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/config/EncryptionAuthenticationMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.config; 9 | 10 | /** 11 | * Enum specifying the value object encryption authentication modes. 12 | * 13 | * @author Elijah Zupancic 14 | * @since 2.8.0 15 | */ 16 | public enum EncryptionAuthenticationMode { 17 | /** 18 | * Optional mode allows for the selective skipping of authentication if it is 19 | * incompatible with an operation being attempted like HTTP range requests. 20 | */ 21 | Optional, 22 | 23 | /** 24 | * Mandatory mode will require that every operation authenticates ciphertext 25 | * and operations that are incompatible will fail with a 26 | * {@link com.joyent.manta.exception.UnauthenticatableOperationException} 27 | * exception. 28 | */ 29 | Mandatory, 30 | 31 | /** 32 | * VerificationDisabled mode will disable ciphertext verification upon decryption. 33 | * HMACs will still be created when encrypting. 34 | */ 35 | VerificationDisabled; 36 | 37 | /** 38 | * The default encryption object authentication mode (Mandatory). 39 | */ 40 | public static final EncryptionAuthenticationMode DEFAULT_MODE = Mandatory; 41 | } 42 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/config/MetricReporterMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.config; 9 | 10 | /** 11 | * Enum specifying the available metric reporting modes. 12 | * 13 | * @author Tomas Celaya 14 | * @since 3.1.9, 3.2.2 15 | */ 16 | public enum MetricReporterMode { 17 | /** 18 | * No metrics will be collected or reported. 19 | */ 20 | DISABLED, 21 | 22 | /** 23 | * Report metrics through JMX (as MBeans). 24 | */ 25 | JMX, 26 | 27 | /** 28 | * Report metrics through SLF4J (as logs). 29 | */ 30 | SLF4J; 31 | 32 | /** 33 | * The default metric reporting mode is to disable metric reporting. 34 | */ 35 | public static final MetricReporterMode DEFAULT = DISABLED; 36 | } 37 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/config/StandardConfigContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.config; 9 | 10 | /** 11 | * Configuration context that is entirely driven by in-memory parameters. 12 | * 13 | * @author Elijah Zupancic 14 | */ 15 | public class StandardConfigContext extends BaseChainedConfigContext { 16 | /** 17 | * Creates a new {@link ConfigContext} implementation that allows for 18 | * programmatic configuration. 19 | */ 20 | public StandardConfigContext() { 21 | super(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/config/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * This package contains classes related to configuring instances of 11 | * {@link com.joyent.manta.client.MantaClient}. 12 | * 13 | *

Design

14 | * 15 | *

When a new instance of {@link com.joyent.manta.client.MantaClient} is created 16 | * it takes a parameter of an instance that implements 17 | * {@link com.joyent.manta.config.ConfigContext}. Within this package are many 18 | * implementations of {@link com.joyent.manta.config.ConfigContext}. By allowing 19 | * for an interface based configuration, we allow users of the SDK to integrate 20 | * into existing configuration systems in their own applications. One example of 21 | * this pattern can be seen in the HadoopConfigurationContext 22 | * class in the hadoop-manta 23 | * project.

24 | * 25 | *

Many of the classes with {@link com.joyent.manta.config} inherit from the 26 | * abstract class {@link com.joyent.manta.config.BaseChainedConfigContext} 27 | * because it supplies methods for allowing you to chain together multiple 28 | * configuration context implementations such that they will support default 29 | * values and allow for layered overwrites of settings.

30 | * 31 | *

For example, the following code would allow you to chain together 32 | * multiple configuration implementations:

33 | * 34 | *
{@code
35 |  * // Creates a composite context from three separate contexts
36 |  * ChainedConfigContext chained = new ChainedConfigContext(
37 |  *     // This context will overwrite both previous contexts if its values are set
38 |  *     new EnvVarConfigContext(),
39 |  *     // This context will overwrite the previous context if its values are set
40 |  *     new MapConfigContext(System.getProperties()),
41 |  *     // This context provides the hardcoded default settings for the Manta client
42 |  *     new DefaultsConfigContext());
43 |  *}
44 | */ 45 | package com.joyent.manta.config; 46 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/domain/Entity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.domain; 9 | 10 | import java.io.Serializable; 11 | import java.util.Map; 12 | 13 | /** 14 | * Interface indicating that an object is considered a core domain object. 15 | * 16 | * @author Elijah Zupancic 17 | * @since 3.0.0 18 | */ 19 | public interface Entity extends Serializable { 20 | 21 | /** 22 | * Converts this object into a {@link Map} that has a key 23 | * for each bean in the object. This is useful for systems that need 24 | * to process each bean as part of an ingestion phase. 25 | * @return Map with each bean as an key/value 26 | */ 27 | Map asMap(); 28 | 29 | /** 30 | * Converts this object into a {@link Map} that has a key 31 | * for each bean in the object and stores the value of each bean as 32 | * a string. This is useful for systems that need to ingest a set of 33 | * plain-text properties for every bean of an instance class. 34 | * @return Map with each bean as a string key/value 35 | */ 36 | Map asStringMap(); 37 | } 38 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/domain/ObjectType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.domain; 9 | 10 | /** 11 | * Enum representing the different types of objects available on Manta. 12 | * 13 | * @author Elijah Zupancic 14 | * @since 3.2.2 15 | */ 16 | public enum ObjectType { 17 | /** 18 | * A remote object that is a logical file. 19 | */ 20 | FILE, 21 | /** 22 | * A remote object that is a logical directory. 23 | */ 24 | DIRECTORY 25 | } 26 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/domain/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing domain objects - objects that are used as representations 11 | * of application state. 12 | * 13 | * @author Elijah Zupancic 14 | * @since 3.0.0 15 | */ 16 | package com.joyent.manta.domain; 17 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/HttpDownloadContinuationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Exception class for fatal errors which may occur while attempting to resumably (resiliently?) download an object. 12 | * The most important aspect of this class is that it does _not_ 13 | * 14 | * @author Tomas Celaya 15 | * @since 3.2.3 16 | */ 17 | public class HttpDownloadContinuationException extends MantaIOException { 18 | 19 | private static final long serialVersionUID = -5972256969855482635L; 20 | 21 | /** 22 | * Constructs an instance with the specified detail message and cause. 23 | * 24 | * @param message The detail message 25 | */ 26 | public HttpDownloadContinuationException(final String message) { 27 | super(message); 28 | } 29 | 30 | /** 31 | * Constructs an instance with the specified detail message and cause. 32 | * 33 | * @param cause The cause 34 | */ 35 | public HttpDownloadContinuationException(final Throwable cause) { 36 | super(cause); 37 | } 38 | 39 | /** 40 | * Constructs an instance with the specified detail message and cause. 41 | * 42 | * @param message The detail message 43 | * @param cause The cause 44 | */ 45 | public HttpDownloadContinuationException(final String message, final Throwable cause) { 46 | super(message, cause); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/HttpDownloadContinuationIncompatibleRequestException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | import com.joyent.manta.util.InputStreamContinuator; 11 | 12 | /** 13 | * Exception indicating that the provided request cannot be reliable auto-resumed. This exception indicates a programmer 14 | * error since the request should've been checked for compatibility before attempting to be supplied to 15 | * {@link InputStreamContinuator}. 16 | * 17 | * @author Tomas Celaya 18 | * @since 3.2.3 19 | */ 20 | public class HttpDownloadContinuationIncompatibleRequestException extends HttpDownloadContinuationException { 21 | 22 | private static final long serialVersionUID = 7415723473743850334L; 23 | 24 | /** 25 | * Constructs an instance with the specified detail message and cause. 26 | * 27 | * @param message The detail message 28 | */ 29 | public HttpDownloadContinuationIncompatibleRequestException(final String message) { 30 | super(message); 31 | } 32 | 33 | 34 | /** 35 | * Constructs an instance with the specified detail message and cause. 36 | * 37 | * @param cause The cause 38 | */ 39 | public HttpDownloadContinuationIncompatibleRequestException(final Throwable cause) { 40 | super(cause); 41 | } 42 | 43 | /** 44 | * Constructs an instance with the specified detail message and cause. 45 | * 46 | * @param message The detail message 47 | * @param cause The cause 48 | */ 49 | public HttpDownloadContinuationIncompatibleRequestException(final String message, final Throwable cause) { 50 | super(message, cause); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/HttpDownloadContinuationUnexpectedResponseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Exception signaling that a resumed download request cannot be continued because the response was invalid. 12 | * 13 | * @author Tomas Celaya 14 | * @since 3.2.3 15 | */ 16 | public class HttpDownloadContinuationUnexpectedResponseException extends HttpDownloadContinuationException { 17 | 18 | private static final long serialVersionUID = 123778476650917899L; 19 | 20 | /** 21 | * Constructs an instance with the specified detail message and cause. 22 | * 23 | * @param message The detail message 24 | */ 25 | public HttpDownloadContinuationUnexpectedResponseException(final String message) { 26 | super(message); 27 | } 28 | 29 | /** 30 | * Constructs an instance with the specified detail message and cause. 31 | * 32 | * @param cause The cause 33 | */ 34 | public HttpDownloadContinuationUnexpectedResponseException(final Throwable cause) { 35 | super(cause); 36 | } 37 | 38 | /** 39 | * Constructs an instance with the specified detail message and cause. 40 | * 41 | * @param message The detail message 42 | * @param cause The cause 43 | */ 44 | public HttpDownloadContinuationUnexpectedResponseException(final String message, final Throwable cause) { 45 | super(message, cause); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaAuthenticationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Exception class that indicates there was a problem authenticating against the 12 | * Manta API. 13 | * 14 | * @author Elijah Zupancic 15 | * @since 3.0.0 16 | */ 17 | public class MantaAuthenticationException extends MantaIOException { 18 | 19 | private static final long serialVersionUID = 3214859017227365745L; 20 | 21 | /** 22 | * Create a new instance with the default message. 23 | */ 24 | public MantaAuthenticationException() { 25 | super("Unable to authenticated against Manta. Check credentials."); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaClientEncryptionCiphertextAuthenticationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Exception representing a failure to authenticate (validate the authenticity) 12 | * of an object's binary ciphertext against a checksum. 13 | * 14 | * @author Elijah Zupancic 15 | * @since 3.0.0 16 | */ 17 | public class MantaClientEncryptionCiphertextAuthenticationException extends MantaClientEncryptionException { 18 | private static final long serialVersionUID = 6663027525586063919L; 19 | 20 | /** 21 | * Default message displayed when exception is thrown. 22 | */ 23 | private static final String DEFAULT_MESSAGE = "Unable to authenticate object's ciphertext. It failed " 24 | + "the authenticity checksum. Check to see that the object's " 25 | + "binary data hasn't been modified."; 26 | 27 | 28 | /** 29 | * Default constructor. 30 | */ 31 | public MantaClientEncryptionCiphertextAuthenticationException() { 32 | super(DEFAULT_MESSAGE); 33 | } 34 | 35 | /** 36 | * @param message The exception message. 37 | */ 38 | public MantaClientEncryptionCiphertextAuthenticationException(final String message) { 39 | super(message); 40 | } 41 | 42 | /** 43 | * @param cause The exception cause. 44 | */ 45 | public MantaClientEncryptionCiphertextAuthenticationException(final Throwable cause) { 46 | super(DEFAULT_MESSAGE, cause); 47 | } 48 | 49 | /** 50 | * @param message The exception message. 51 | * @param cause The exception cause. 52 | */ 53 | public MantaClientEncryptionCiphertextAuthenticationException(final String message, final Throwable cause) { 54 | super(message, cause); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaClientEncryptionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Root exception type for all client-side encryption exceptions. 12 | * 13 | * @author Elijah Zupancic 14 | * @since 3.0.0 15 | */ 16 | public class MantaClientEncryptionException extends MantaEncryptionException { 17 | private static final long serialVersionUID = -1687775226513239704L; 18 | 19 | /** 20 | * Default constructor. 21 | */ 22 | public MantaClientEncryptionException() { 23 | } 24 | 25 | /** 26 | * @param message The exception message. 27 | */ 28 | public MantaClientEncryptionException(final String message) { 29 | super(message); 30 | } 31 | 32 | /** 33 | * @param cause The exception cause. 34 | */ 35 | public MantaClientEncryptionException(final Throwable cause) { 36 | super(cause); 37 | } 38 | 39 | /** 40 | * @param message The exception message. 41 | * @param cause The exception cause. 42 | */ 43 | public MantaClientEncryptionException(final String message, final Throwable cause) { 44 | super(message, cause); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaClientException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * General exception class for Manta client exceptions. 12 | * 13 | * @author Yunong Xiao 14 | */ 15 | public class MantaClientException extends MantaException { 16 | private static final long serialVersionUID = 4004550753800130185L; 17 | 18 | /** 19 | * Create an empty exception. 20 | */ 21 | public MantaClientException() { 22 | } 23 | 24 | /** 25 | * @param message The error message. 26 | */ 27 | public MantaClientException(final String message) { 28 | super(message); 29 | } 30 | 31 | /** 32 | * @param cause The cause of the exception. 33 | */ 34 | public MantaClientException(final Throwable cause) { 35 | super(cause); 36 | } 37 | 38 | /** 39 | * @param message The error message. 40 | * @param cause The cause. 41 | */ 42 | public MantaClientException(final String message, final Throwable cause) { 43 | super(message, cause); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaEncryptionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Root exception type for all encryption exceptions. 12 | * 13 | * @author Elijah Zupancic 14 | * @since 3.0.0 15 | */ 16 | public class MantaEncryptionException extends MantaException { 17 | private static final long serialVersionUID = -1210560907538988566L; 18 | 19 | /** 20 | * Default constructor. 21 | */ 22 | public MantaEncryptionException() { 23 | } 24 | 25 | /** 26 | * @param message The exception message. 27 | */ 28 | public MantaEncryptionException(final String message) { 29 | super(message); 30 | } 31 | 32 | /** 33 | * @param cause The exception cause. 34 | */ 35 | public MantaEncryptionException(final Throwable cause) { 36 | super(cause); 37 | } 38 | 39 | /** 40 | * @param message The exception message. 41 | * @param cause The exception cause. 42 | */ 43 | public MantaEncryptionException(final String message, final Throwable cause) { 44 | super(message, cause); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | import com.joyent.manta.util.MantaVersion; 11 | import org.apache.commons.lang3.exception.ContextedRuntimeException; 12 | 13 | /** 14 | * The base MantaException class. 15 | * @author Yunong Xiao 16 | */ 17 | public class MantaException extends ContextedRuntimeException { 18 | 19 | private static final long serialVersionUID = 146894136987570504L; 20 | 21 | { 22 | addContextValue("mantaSdkVersion", MantaVersion.VERSION); 23 | } 24 | 25 | /** 26 | * Default constructor. 27 | */ 28 | public MantaException() { 29 | } 30 | 31 | /** 32 | * @param message The exception message. 33 | */ 34 | public MantaException(final String message) { 35 | super(message); 36 | } 37 | 38 | /** 39 | * @param cause The exception cause. 40 | */ 41 | public MantaException(final Throwable cause) { 42 | super(cause); 43 | } 44 | 45 | /** 46 | * @param message The exception message. 47 | * @param cause The exception cause. 48 | */ 49 | public MantaException(final String message, final Throwable cause) { 50 | super(message, cause); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaMemoizationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Exception class for errors related to encryption state memoization. 12 | */ 13 | public class MantaMemoizationException extends MantaEncryptionException { 14 | 15 | private static final long serialVersionUID = 5416151858078164147L; 16 | 17 | /** 18 | * @param message The error message. 19 | */ 20 | public MantaMemoizationException(final String message) { 21 | super(message); 22 | } 23 | 24 | /** 25 | * @param cause The cause of the exception. 26 | */ 27 | public MantaMemoizationException(final Throwable cause) { 28 | super(cause); 29 | } 30 | 31 | /** 32 | * @param message The error message. 33 | * @param cause The cause. 34 | */ 35 | public MantaMemoizationException(final String message, final Throwable cause) { 36 | super(message, cause); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaMultipartException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * General exception type for errors relating to multipart uploads. 12 | * 13 | * @since 2.5.0 14 | * @author Elijah Zupancic 15 | */ 16 | public class MantaMultipartException extends MantaClientException { 17 | 18 | private static final long serialVersionUID = -1931282527258322479L; 19 | 20 | /** 21 | * Create an empty exception. 22 | */ 23 | public MantaMultipartException() { 24 | } 25 | 26 | /** 27 | * @param message The error message. 28 | */ 29 | public MantaMultipartException(final String message) { 30 | super(message); 31 | } 32 | 33 | /** 34 | * @param cause The cause of the exception. 35 | */ 36 | public MantaMultipartException(final Throwable cause) { 37 | super(cause); 38 | } 39 | 40 | /** 41 | * @param message The error message. 42 | * @param cause The cause. 43 | */ 44 | public MantaMultipartException(final String message, final Throwable cause) { 45 | super(message, cause); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaObjectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * @author Yunong Xiao 12 | */ 13 | public class MantaObjectException extends MantaException { 14 | 15 | private static final long serialVersionUID = 6799144229159150444L; 16 | 17 | /** 18 | * Default constructor. 19 | */ 20 | public MantaObjectException() { 21 | } 22 | 23 | /** 24 | * @param message The exception message. 25 | */ 26 | public MantaObjectException(final String message) { 27 | super(message); 28 | } 29 | 30 | /** 31 | * @param cause The exception cause. 32 | */ 33 | public MantaObjectException(final Throwable cause) { 34 | super(cause); 35 | } 36 | 37 | /** 38 | * @param message The exception message. 39 | * @param cause The exception cause. 40 | */ 41 | public MantaObjectException(final String message, final Throwable cause) { 42 | super(message, cause); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/MantaReflectionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Exception class for errors related to encryption state memoization. 12 | */ 13 | public class MantaReflectionException extends MantaException { 14 | 15 | private static final long serialVersionUID = 8476251230398493965L; 16 | 17 | /** 18 | * @param message The exception message. 19 | */ 20 | public MantaReflectionException(final String message) { 21 | super(message); 22 | } 23 | 24 | /** 25 | * @param cause The exception cause. 26 | */ 27 | public MantaReflectionException(final Exception cause) { 28 | super(cause); 29 | } 30 | 31 | /** 32 | * @param message The exception message. 33 | * @param cause The exception cause. 34 | */ 35 | public MantaReflectionException(final String message, final Exception cause) { 36 | super(message, cause); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/UnauthenticatableOperationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | /** 11 | * Exception thrown when an operation that doesn't support authentication was 12 | * attempted when running in EncryptionAuthenticationMode.Mandatory mode. 13 | * 14 | * @author Elijah Zupancic 15 | * @since 2.8.0 16 | */ 17 | public class UnauthenticatableOperationException 18 | extends MantaClientEncryptionException { 19 | private static final long serialVersionUID = 6129395920967997954L; 20 | 21 | /** 22 | * Default constructor. 23 | */ 24 | public UnauthenticatableOperationException() { 25 | } 26 | 27 | /** 28 | * @param message The exception message. 29 | */ 30 | public UnauthenticatableOperationException(final String message) { 31 | super(message); 32 | } 33 | 34 | /** 35 | * @param cause The exception cause. 36 | */ 37 | public UnauthenticatableOperationException(final Throwable cause) { 38 | super(cause); 39 | } 40 | 41 | /** 42 | * @param message The exception message. 43 | * @param cause The exception cause. 44 | */ 45 | public UnauthenticatableOperationException(final String message, final Throwable cause) { 46 | super(message, cause); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/exception/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Manta Java client exception package. 11 | * @author Yunong Xiao 12 | */ 13 | package com.joyent.manta.exception; 14 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/DynamicHttpSignatureRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import com.joyent.http.signature.apache.httpclient.HttpSignatureAuthScheme; 11 | import com.joyent.manta.config.AuthAwareConfigContext; 12 | import org.apache.http.Header; 13 | import org.apache.http.HttpException; 14 | import org.apache.http.HttpRequest; 15 | import org.apache.http.HttpRequestInterceptor; 16 | import org.apache.http.protocol.HttpContext; 17 | 18 | import java.io.IOException; 19 | 20 | /** 21 | * Request interceptor which can read potentially-changing authentication configuration from a 22 | * {@link AuthAwareConfigContext}. 23 | * 24 | * @author Tomas Celaya 25 | * @since 3.1.7 26 | */ 27 | class DynamicHttpSignatureRequestInterceptor implements HttpRequestInterceptor { 28 | 29 | /** 30 | * The auth context from which to read the {@link HttpSignatureAuthScheme} and 31 | * {@link org.apache.http.auth.Credentials}. 32 | */ 33 | private final AuthAwareConfigContext authConfig; 34 | 35 | /** 36 | * Create an interceptor which will read authentication objects from a dynamic configuration. 37 | * 38 | * @param authConfig authentication context 39 | */ 40 | DynamicHttpSignatureRequestInterceptor(final AuthAwareConfigContext authConfig) { 41 | this.authConfig = authConfig; 42 | } 43 | 44 | @Override 45 | public void process(final HttpRequest request, final HttpContext context) 46 | throws HttpException, IOException { 47 | if (authConfig.noAuth()) { 48 | return; 49 | } 50 | 51 | final long start = System.nanoTime(); 52 | final HttpSignatureAuthScheme authScheme = authConfig.getAuthScheme(); 53 | final Header authorization = authScheme.authenticate(authConfig.getCredentials(), request, context); 54 | final long end = System.nanoTime(); 55 | 56 | request.setHeader(authorization); 57 | request.setHeader("x-http-signing-time-ns", String.valueOf(end - start)); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/HttpConnectionAware.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | /** 11 | * Interface indicating a class has access to a {@link MantaConnectionContext}. 12 | * 13 | * @author Tomas Celaya 14 | * @since 3.1.7 15 | */ 16 | interface HttpConnectionAware { 17 | 18 | /** 19 | * Retrieve the attached {@link MantaConnectionContext}. 20 | * 21 | * @return the context 22 | */ 23 | MantaConnectionContext getConnectionContext(); 24 | 25 | /** 26 | * HTTP Request creation object. 27 | * @return request creation object for use with the above connection 28 | */ 29 | MantaHttpRequestFactory getRequestFactory(); 30 | } 31 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/HttpContextRetryCancellation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import org.apache.http.protocol.HttpContext; 11 | 12 | /** 13 | * Interface indicating that an implementing class checks the request/response context for a flag indicating that 14 | * automatic retries should not occur. 15 | * 16 | * @author Tomas Celaya 17 | * @since 3.2.3 18 | */ 19 | public interface HttpContextRetryCancellation { 20 | 21 | /** 22 | * The reserved context key name. 23 | */ 24 | String CONTEXT_ATTRIBUTE_MANTA_RETRY_DISABLE = "manta.retry.disable"; 25 | 26 | /** 27 | * Check if the given context contains the reserved key and it is enabled. 28 | * 29 | * @param context the context to check 30 | * @return whether or not retries are disabled 31 | */ 32 | default boolean neverRetry(final HttpContext context) { 33 | final Object disableRetry = context.getAttribute(CONTEXT_ATTRIBUTE_MANTA_RETRY_DISABLE); 34 | 35 | return disableRetry instanceof Boolean && (Boolean) disableRetry; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/MantaConnectionContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import com.joyent.manta.util.MetricsAware; 11 | import org.apache.http.impl.client.CloseableHttpClient; 12 | 13 | import java.io.IOException; 14 | 15 | /** 16 | * Interface describing the contract for a context class that stores state between requests to the Manta API. 17 | * 18 | * @author Elijah Zupancic 19 | * @since 3.0.0 20 | */ 21 | public interface MantaConnectionContext extends AutoCloseable, RetryConfigAware, MetricsAware { 22 | 23 | /** 24 | * HTTP client object used for accessing Manta. 25 | * 26 | * @return connection object to Manta 27 | */ 28 | CloseableHttpClient getHttpClient(); 29 | 30 | /** 31 | * {@inheritDoc} 32 | * 33 | *

Note: This changes the signature of {@link AutoCloseable#close()} to 34 | * only throw {@link IOException}.

35 | * 36 | * @throws IOException thrown if there was a problem closing resources 37 | */ 38 | @Override 39 | void close() throws IOException; 40 | } 41 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/MantaConnectionFactoryConfigurator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import org.apache.commons.lang3.Validate; 11 | import org.apache.http.conn.HttpClientConnectionManager; 12 | import org.apache.http.impl.client.HttpClientBuilder; 13 | 14 | /** 15 | * Object for providing pre-configured HttpClient objects to use with {@link MantaConnectionFactory}. 16 | * 17 | * @author Tomas Celaya 18 | * @since 3.1.7 19 | */ 20 | public class MantaConnectionFactoryConfigurator { 21 | 22 | /** 23 | * An existing {@link HttpClientBuilder} to further configure. 24 | */ 25 | private final HttpClientBuilder httpClientBuilder; 26 | 27 | /** 28 | * Packages together an externally-configured {@link HttpClientBuilder} and {@link HttpClientConnectionManager} 29 | * for use with the {@link com.joyent.manta.client.MantaClient} through a {@link MantaConnectionFactory}. 30 | * 31 | * @param httpClientBuilder the client builder 32 | */ 33 | public MantaConnectionFactoryConfigurator(final HttpClientBuilder httpClientBuilder) { 34 | Validate.notNull(httpClientBuilder, "HttpClientBuilder must not be null"); 35 | 36 | this.httpClientBuilder = httpClientBuilder; 37 | } 38 | 39 | HttpClientBuilder getHttpClientBuilder() { 40 | return httpClientBuilder; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/MantaContentTypes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import org.apache.http.entity.ContentType; 11 | 12 | /** 13 | * Enum defining custom content-types used only by Manta. 14 | * 15 | * @author Elijah Zupancic 16 | * @since 3.0.0 17 | */ 18 | public enum MantaContentTypes { 19 | /** 20 | * The content-type used to represent Manta directory resources in http requests. 21 | */ 22 | DIRECTORY_LIST("application/json; type=directory"), 23 | 24 | /** 25 | * The content-type used to represent Manta link resources. 26 | */ 27 | SNAPLINK("application/json; type=link"), 28 | 29 | /** 30 | * The content-type used to represent encrypted objects. 31 | */ 32 | ENCRYPTED_OBJECT(ContentType.APPLICATION_OCTET_STREAM.toString()); 33 | 34 | /** 35 | * Plain-text representation of the enum's content-type. 36 | */ 37 | private final String contentType; 38 | 39 | /** 40 | * Creates a new instance with the specified content-type. 41 | * 42 | * @param contentType content-type to initialize 43 | */ 44 | MantaContentTypes(final String contentType) { 45 | this.contentType = contentType; 46 | } 47 | 48 | /** 49 | * @return the RFC 2616 content-type 50 | */ 51 | public String getContentType() { 52 | return this.contentType; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return getContentType(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/RequestIdInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import com.fasterxml.uuid.EthernetAddress; 11 | import com.fasterxml.uuid.Generators; 12 | import com.fasterxml.uuid.impl.TimeBasedGenerator; 13 | import org.apache.http.Header; 14 | import org.apache.http.HttpException; 15 | import org.apache.http.HttpRequest; 16 | import org.apache.http.HttpRequestInterceptor; 17 | import org.apache.http.message.BasicHeader; 18 | import org.apache.http.protocol.HttpContext; 19 | import org.slf4j.MDC; 20 | 21 | import java.io.IOException; 22 | import java.security.NoSuchAlgorithmException; 23 | import java.security.NoSuchProviderException; 24 | import java.security.SecureRandom; 25 | import java.util.Random; 26 | import java.util.UUID; 27 | 28 | /** 29 | * Add the request id for an HTTP header to the SLF4J MDC logging implementation. This 30 | * is useful because it allows us to view the request id in all of the logs associated 31 | * with the request. 32 | * 33 | * @author Elijah Zupancic 34 | * @since 3.0.0 35 | */ 36 | public class RequestIdInterceptor implements HttpRequestInterceptor { 37 | /** 38 | * Time-based UUID generator for generating request ids. 39 | */ 40 | private static final TimeBasedGenerator TIME_BASED_GENERATOR; 41 | 42 | static { 43 | Random nonBlockingRandomness; 44 | 45 | try { 46 | nonBlockingRandomness = SecureRandom.getInstance("NativePRNGNonBlocking", "SUN"); 47 | } catch (NoSuchAlgorithmException | NoSuchProviderException e) { 48 | nonBlockingRandomness = new Random(System.nanoTime()); 49 | } 50 | 51 | // Fake ethernet address based on a random value 52 | final EthernetAddress ethernetAddress = EthernetAddress.constructMulticastAddress( 53 | nonBlockingRandomness); 54 | TIME_BASED_GENERATOR = Generators.timeBasedGenerator(ethernetAddress); 55 | } 56 | 57 | /** 58 | * Constant identifying the request id as a MDC attribute. 59 | */ 60 | public static final String MDC_REQUEST_ID_STRING = "mantaRequestId"; 61 | 62 | @Override 63 | public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { 64 | final UUID id = TIME_BASED_GENERATOR.generate(); 65 | final String requestId = id.toString(); 66 | final Header idHeader = new BasicHeader(MantaHttpHeaders.REQUEST_ID, requestId); 67 | request.addHeader(idHeader); 68 | 69 | MDC.put(MDC_REQUEST_ID_STRING, requestId); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/RetryConfigAware.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | /** 11 | * Interface indicating that an object understands the underlying retry behavior and a common key to use 12 | * when indicating that retry cancellation is possible through {@link HttpContextRetryCancellation}. 13 | * 14 | * @author Tomas Celaya 15 | * @since 3.2.3 16 | */ 17 | public interface RetryConfigAware { 18 | 19 | /** 20 | * Whether or not automatic retries are enabled. 21 | * 22 | * @return if retries are enabled 23 | */ 24 | boolean isRetryEnabled(); 25 | 26 | /** 27 | * Whether or not retries can be cancelled using {@link HttpContextRetryCancellation}. 28 | * 29 | * @return if retry cancellation is supported 30 | */ 31 | boolean isRetryCancellable(); 32 | } 33 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/ShufflingDnsResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import org.apache.http.conn.DnsResolver; 11 | 12 | import java.net.InetAddress; 13 | import java.net.UnknownHostException; 14 | import java.util.Random; 15 | import java.util.concurrent.ThreadLocalRandom; 16 | 17 | /** 18 | * Implementation {@link DnsResolver} that shuffles the results of a DNS query 19 | * upon every query, so that we get better distribution of connections to 20 | * different hosts backed by the same name. 21 | * 22 | * @author Elijah Zupancic 23 | */ 24 | public class ShufflingDnsResolver implements DnsResolver { 25 | @Override 26 | public InetAddress[] resolve(final String host) throws UnknownHostException { 27 | final InetAddress[] addresses = InetAddress.getAllByName(host); 28 | shuffle(addresses); 29 | 30 | return addresses; 31 | } 32 | 33 | /** 34 | * Shuffles an array of addresses that were returned from a DNS query. 35 | * Shuffle algorithm inspired by this stackoverflow post. 36 | * @param addresses addresses to shuffle 37 | */ 38 | private static void shuffle(final InetAddress[] addresses) { 39 | // Only shuffle if we have 2 or more addresses 40 | if (addresses.length < 2) { 41 | return; 42 | } 43 | 44 | Random random = ThreadLocalRandom.current(); 45 | 46 | for (int i = addresses.length - 1; i > 0; i--) { 47 | int index = random.nextInt(i + 1); 48 | // Simple swap 49 | InetAddress a = addresses[index]; 50 | addresses[index] = addresses[i]; 51 | addresses[i] = a; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/entity/MantaInputStreamEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http.entity; 9 | 10 | import org.apache.http.entity.ContentType; 11 | import org.apache.http.entity.InputStreamEntity; 12 | 13 | import java.io.InputStream; 14 | 15 | /** 16 | * A Manta-specific implementation of {@link org.apache.http.entity.InputStreamEntity}. 17 | * 18 | * @author Elijah Zupancic 19 | * @since 3.0.0 20 | */ 21 | public class MantaInputStreamEntity extends InputStreamEntity { 22 | /** 23 | * Creates an entity with an unknown length. 24 | * Equivalent to {@code new InputStreamEntity(instream, -1)}. 25 | * 26 | * @param instream input stream 27 | * @throws IllegalArgumentException if {@code instream} is {@code null} 28 | */ 29 | public MantaInputStreamEntity(final InputStream instream) { 30 | super(instream); 31 | } 32 | 33 | /** 34 | * Creates an entity with a specified content length. 35 | * 36 | * @param instream input stream 37 | * @param length of the input stream, {@code -1} if unknown 38 | * @throws IllegalArgumentException if {@code instream} is {@code null} 39 | */ 40 | public MantaInputStreamEntity(final InputStream instream, final long length) { 41 | super(instream, length); 42 | } 43 | 44 | /** 45 | * Creates an entity with a content type and unknown length. 46 | * Equivalent to {@code new InputStreamEntity(instream, -1, contentType)}. 47 | * 48 | * @param instream input stream 49 | * @param contentType content type 50 | * @throws IllegalArgumentException if {@code instream} is {@code null} 51 | */ 52 | public MantaInputStreamEntity(final InputStream instream, final ContentType contentType) { 53 | super(instream, contentType); 54 | } 55 | 56 | /** 57 | * @param instream input stream 58 | * @param length of the input stream, {@code -1} if unknown 59 | * @param contentType for specifying the {@code Content-Type} header, may be {@code null} 60 | * @throws IllegalArgumentException if {@code instream} is {@code null} 61 | */ 62 | public MantaInputStreamEntity(final InputStream instream, final long length, 63 | final ContentType contentType) { 64 | super(instream, length, contentType); 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/entity/MemoryBackedEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http.entity; 9 | 10 | import java.nio.ByteBuffer; 11 | 12 | /** 13 | * Provides an interface for entity that can expose a backing buffer of their 14 | * content. 15 | * 16 | * @author Elijah Zupancic 17 | * @since 3.0.0 18 | */ 19 | public interface MemoryBackedEntity { 20 | /** 21 | * @return the backing byte array as a {@link ByteBuffer} instance 22 | */ 23 | ByteBuffer getBackingBuffer(); 24 | } 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/entity/NoContentEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http.entity; 9 | 10 | import org.apache.http.Header; 11 | import org.apache.http.HttpEntity; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.OutputStream; 16 | 17 | /** 18 | * Entity type used when not sending any content to the server. 19 | * 20 | * @author Elijah Zupancic 21 | * @since 3.0.0 22 | */ 23 | public final class NoContentEntity implements HttpEntity { 24 | /** 25 | * Constant indicating an unknown content length. 26 | */ 27 | private static final long NO_CONTENT_LENGTH = -1L; 28 | 29 | /** 30 | * Reusable instance of entity class. 31 | */ 32 | public static final NoContentEntity INSTANCE = new NoContentEntity(); 33 | 34 | /** 35 | * Private constructor because a single instance is all that we need. 36 | */ 37 | private NoContentEntity() { 38 | 39 | } 40 | 41 | @Override 42 | public boolean isRepeatable() { 43 | return true; 44 | } 45 | 46 | @Override 47 | public boolean isChunked() { 48 | return true; 49 | } 50 | 51 | @Override 52 | public long getContentLength() { 53 | return NO_CONTENT_LENGTH; 54 | } 55 | 56 | @Override 57 | public Header getContentType() { 58 | return null; 59 | } 60 | 61 | @Override 62 | public Header getContentEncoding() { 63 | return null; 64 | } 65 | 66 | @Override 67 | public InputStream getContent() throws IOException, UnsupportedOperationException { 68 | return null; 69 | } 70 | 71 | @Override 72 | public void writeTo(final OutputStream outstream) throws IOException { 73 | } 74 | 75 | @Override 76 | public boolean isStreaming() { 77 | return false; 78 | } 79 | 80 | @Deprecated 81 | @Override 82 | public void consumeContent() throws IOException { 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/entity/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing implementations of {@link org.apache.http.HttpEntity}. 11 | * 12 | * @author Elijah Zupancic 13 | * @since 1.0.0 14 | */ 15 | package com.joyent.manta.http.entity; 16 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/http/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing classes used for accessing Manta over HTTP(S). 11 | * 12 | * @author Elijah Zupancic 13 | * @since 3.0.0 14 | */ 15 | package com.joyent.manta.http; 16 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/CipherCloner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import com.joyent.manta.client.crypto.ExternalSecurityProviderLoader; 11 | import com.joyent.manta.exception.MantaMemoizationException; 12 | 13 | import javax.crypto.Cipher; 14 | import java.security.Provider; 15 | 16 | /** 17 | * Utility class for cloning Cipher objects. 18 | */ 19 | public final class CipherCloner implements Cloner { 20 | 21 | /** 22 | * Instance of object-cloning library that does deep generic cloning. 23 | */ 24 | private static final com.rits.cloning.Cloner INSTANCE = new com.rits.cloning.Cloner(); 25 | 26 | static { 27 | // omit deep-cloning of classes which don't hold cipher state 28 | // references will be copied directly instead of recursively cloned 29 | INSTANCE.dontCloneInstanceOf(Class.class, Provider.class); 30 | } 31 | 32 | @Override 33 | public Cipher createClone(final Cipher source) { 34 | /* We are assured that the PKCS11 provider we are getting is libnss and 35 | * we know that it isn't possible to clone ciphers from this provider. */ 36 | final Provider pkcs11Provider = ExternalSecurityProviderLoader.getPkcs11Provider(); 37 | /* This is the provider of the input cipher and we will not know what 38 | * provider it is until run time. */ 39 | final Provider cipherProvider = source.getProvider(); 40 | 41 | /* We need to validate that the provider as given from the supplied 42 | * cipher is not backed by a libnss provider because it is unclonable. 43 | * In that case, we want to emit an exception that leads a developer to 44 | * a sensible error message rather than the inscrutable message that is 45 | * returned if we attempt the clone operation. */ 46 | 47 | if (pkcs11Provider != null && cipherProvider.equals(pkcs11Provider)) { 48 | String msg = String.format("Cannot create clone of Cipher with provider: %s", 49 | source.getProvider()); 50 | throw new MantaMemoizationException(msg); 51 | } 52 | 53 | return INSTANCE.deepClone(source); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/Cloner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | /** 11 | * Interface indicating a class which is designed to create fully independent clones. 12 | * 13 | * @param type to clone 14 | */ 15 | public interface Cloner { 16 | 17 | /** 18 | * Generates a new {@code T} using values from {@code source}. 19 | * 20 | * @param source the source of state to use 21 | * @return a brand new {@code T} 22 | */ 23 | T createClone(T source); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/DigestCloner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import com.joyent.manta.exception.MantaMemoizationException; 11 | import org.bouncycastle.crypto.Digest; 12 | import org.bouncycastle.util.Memoable; 13 | 14 | /** 15 | * Utility class for cloning Digest objects. 16 | */ 17 | public final class DigestCloner implements Cloner { 18 | 19 | @Override 20 | public Digest createClone(final Digest source) { 21 | if (source instanceof Memoable) { 22 | return (Digest) ((Memoable) source).copy(); 23 | } 24 | 25 | // we expect all Digest objects to implement Memoable 26 | throw new MantaMemoizationException("Clone not implemented for type: " + source.getClass().getCanonicalName()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/HmacCloner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import com.joyent.manta.exception.MantaReflectionException; 11 | import org.bouncycastle.crypto.Digest; 12 | import org.bouncycastle.crypto.macs.HMac; 13 | import org.bouncycastle.util.Memoable; 14 | 15 | import java.lang.reflect.Field; 16 | 17 | import static org.apache.commons.lang3.reflect.FieldUtils.getField; 18 | import static org.apache.commons.lang3.reflect.FieldUtils.readField; 19 | import static org.apache.commons.lang3.reflect.FieldUtils.writeField; 20 | 21 | /** 22 | * Utility class for cloning HMac objects. 23 | */ 24 | public final class HmacCloner implements Cloner { 25 | 26 | /** 27 | * Private field on {@link HMac} to query for ipad state. 28 | */ 29 | private static final Field FIELD_IPAD_STATE = getField(HMac.class, "ipadState", true); 30 | 31 | /** 32 | * Private field on {@link HMac} to query for opad state. 33 | */ 34 | private static final Field FIELD_OPAD_STATE = getField(HMac.class, "opadState", true); 35 | 36 | @Override 37 | public HMac createClone(final HMac source) { 38 | final Digest originalDigest = source.getUnderlyingDigest(); 39 | final Digest clonedDigest = new DigestCloner().createClone(originalDigest); 40 | final HMac cloned = new HMac(clonedDigest); 41 | 42 | try { 43 | final Memoable ipadState = (Memoable) readField(FIELD_IPAD_STATE, source, true); 44 | final Memoable opadState = (Memoable) readField(FIELD_OPAD_STATE, source, true); 45 | 46 | writeField(FIELD_IPAD_STATE, cloned, ipadState.copy()); 47 | writeField(FIELD_OPAD_STATE, cloned, opadState.copy()); 48 | } catch (IllegalAccessException e) { 49 | throw new MantaReflectionException(e); 50 | } 51 | 52 | return cloned; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/HmacOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import org.apache.commons.lang3.Validate; 11 | import org.bouncycastle.crypto.macs.HMac; 12 | 13 | import java.io.IOException; 14 | import java.io.OutputStream; 15 | 16 | /** 17 | * {@link OutputStream} implementation that progressively updates a 18 | * HMAC as data is written. 19 | * 20 | * @author Elijah Zupancic 21 | * @since 3.0.0 22 | */ 23 | public class HmacOutputStream extends OutputStream { 24 | /** 25 | * HMAC instance used to generate HMAC for wrapped stream. 26 | */ 27 | private HMac hmac; 28 | 29 | /** 30 | * Underlying stream being wrapped. 31 | */ 32 | private OutputStream out; 33 | 34 | /** 35 | * Private constructor used for serialization. 36 | */ 37 | private HmacOutputStream() { 38 | } 39 | 40 | /** 41 | * Creates a new instance using the specified HMAC instance and wrapping 42 | * the specified stream. 43 | * 44 | * @param hmac HMAC instance that has been initialized 45 | * @param chained stream being wrapped 46 | */ 47 | public HmacOutputStream(final HMac hmac, final OutputStream chained) { 48 | Validate.notNull(hmac, "HMAC instance must not be null"); 49 | Validate.notNull(chained, "OutputStream must not be null"); 50 | 51 | this.hmac = hmac; 52 | this.out = chained; 53 | } 54 | 55 | public HMac getHmac() { 56 | return hmac; 57 | } 58 | 59 | @Override 60 | public void write(final int b) throws IOException { 61 | hmac.update((byte)b); 62 | out.write(b); 63 | } 64 | 65 | @Override 66 | public void write(final byte[] buffer) throws IOException { 67 | hmac.update(buffer, 0, buffer.length); 68 | out.write(buffer); 69 | } 70 | 71 | @Override 72 | public void write(final byte[] buffer, final int offset, final int length) throws IOException { 73 | hmac.update(buffer, offset, length); 74 | out.write(buffer, offset, length); 75 | } 76 | 77 | @Override 78 | public void flush() throws IOException { 79 | out.flush(); 80 | } 81 | 82 | @Override 83 | public void close() throws IOException { 84 | out.close(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/InputStreamContinuator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import java.io.Closeable; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | 14 | /** 15 | * "Factory" class for resuming the body of a response being read as an {@link InputStream} based on the number of bytes 16 | * already read. Meant to be used in combination with {@link com.joyent.manta.util.ContinuingInputStream}. The 17 | * {@link Closeable} is included so that the number of continuations provided by a single continuator can be 18 | * instrumented. 19 | * 20 | * Could also be called "InputStreamFactory" or "InputStreamContinuationFactory" but those are a bit too ambiguous. 21 | * 22 | * @author Tomas Celaya 23 | * @since 3.2.3 24 | */ 25 | public interface InputStreamContinuator extends Closeable { 26 | 27 | /** 28 | * Get an {@link InputStream} which picks up starting {@code bytesRead} bytes from the beginning of the logical 29 | * object being downloaded. Implementations should compare headers across all requests and responses to ensure 30 | * that the object being downloaded has not changed between the initial and subsequent requests. 31 | * 32 | * @param ex the exception which occurred while downloading (either the first response or a continuation) 33 | * @param bytesRead byte offset at which the new stream should start 34 | * @return another stream which continues to deliver the bytes from the initial request 35 | * @throws IOException if the exception is not recoverable or there is an error preparing the continuation 36 | */ 37 | InputStream buildContinuation(IOException ex, long bytesRead) throws IOException; 38 | } 39 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/MantaVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import java.time.Instant; 11 | 12 | /** 13 | * Utility class providing the current version of the SDK. 14 | */ 15 | public final class MantaVersion { 16 | /** 17 | * No public constructor because only static methods are exposed. 18 | */ 19 | private MantaVersion() { 20 | } 21 | 22 | /** 23 | * Release version of the SDK. 24 | */ 25 | public static final String VERSION = "3.4.4-SNAPSHOT"; 26 | 27 | /** 28 | * Minimum version of client-side encryption supported. 29 | */ 30 | public static final int CLIENT_SIDE_ENCRYPTION_MIN_VERSION = 1; 31 | 32 | /** 33 | * Maximum version of client-side encryption supported. 34 | */ 35 | public static final int CLIENT_SIDE_ENCRYPTION_MAX_VERSION = 1; 36 | 37 | /** 38 | * Release date of the SDK. 39 | */ 40 | public static final Instant DATE = Instant.now(); 41 | } 42 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/MetricsAware.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import com.joyent.manta.config.MantaClientMetricConfiguration; 11 | 12 | /** 13 | * Marker interface indicating that a class may carry a metric configuration (or encapsulate something that does). 14 | * Returning null is acceptable and indicates that metric collection is disabled. 15 | * 16 | * @author Tomas Celaya 17 | * @since 3.2.3 18 | */ 19 | public interface MetricsAware { 20 | 21 | /** 22 | * Get the configuration. 23 | * 24 | * @return null or the configuration 25 | */ 26 | MantaClientMetricConfiguration getMetricConfig(); 27 | } 28 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/NotThreadSafe.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ==================================================================== 3 | * Licensed to the Apache Software Foundation (ASF) under one 4 | * or more contributor license agreements. See the NOTICE file 5 | * distributed with this work for additional information 6 | * regarding copyright ownership. The ASF licenses this file 7 | * to you under the Apache License, Version 2.0 (the 8 | * "License"); you may not use this file except in compliance 9 | * with the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | * ==================================================================== 20 | * 21 | * This software consists of voluntary contributions made by many 22 | * individuals on behalf of the Apache Software Foundation. For more 23 | * information on the Apache Software Foundation, please see 24 | * . 25 | * 26 | */ 27 | package com.joyent.manta.util; 28 | 29 | import java.lang.annotation.Documented; 30 | import java.lang.annotation.ElementType; 31 | import java.lang.annotation.Retention; 32 | import java.lang.annotation.RetentionPolicy; 33 | import java.lang.annotation.Target; 34 | 35 | /** 36 | *

The class to which this annotation is applied is not thread-safe. 37 | * This annotation primarily exists for clarifying the non-thread-safety of a 38 | * class that might otherwise be assumed to be thread-safe, despite the fact 39 | * that it is a bad idea to assume a class is thread-safe without good reason.

40 | * 41 | *

Based on code developed by Brian Goetz and Tim Peierls and concepts 42 | * published in 'Java Concurrency in Practice' by Brian Goetz, Tim Peierls, 43 | * Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea.

44 | * 45 | *

The only modifications to this class from its original is this block 46 | * comment and the package name

47 | * 48 | * @see Apache httpcore Implementation 49 | */ 50 | @Documented 51 | @Target(ElementType.TYPE) 52 | @Retention(RetentionPolicy.CLASS) // The original version used RUNTIME 53 | public @interface NotThreadSafe { 54 | } 55 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/joyent/manta/util/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing utility classes. 11 | * 12 | * @author Elijah Zupancic 13 | * @since 3.0.0 14 | */ 15 | package com.joyent.manta.util; 16 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/main/java/com/twmacinta/util/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Package containing helper classes for Timothy W Macinta's FastMD5 11 | * implementation. 12 | * 13 | * @author Elijah Zupancic 14 | * @since 3.0.0 15 | */ 16 | package com.twmacinta.util; 17 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/client/crypto/ByteRangeConversionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.crypto; 9 | 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | 14 | @Test 15 | public class ByteRangeConversionTest { 16 | public void setsCorrectProperties() { 17 | ByteRangeConversion byteConversion = new ByteRangeConversion(100, 10, 80, 70, 1); 18 | Assert.assertEquals(byteConversion.getCiphertextStartPositionInclusive(), 100); 19 | Assert.assertEquals(byteConversion.getPlaintextBytesToSkipInitially(), 10); 20 | Assert.assertEquals(byteConversion.getCiphertextEndPositionInclusive(), 80); 21 | Assert.assertEquals(byteConversion.getLengthOfPlaintextIncludingSkipBytes(), 70); 22 | Assert.assertEquals(byteConversion.getStartingBlockNumberInclusive(), 1); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/client/crypto/IncompleteByteReadInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.crypto; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | 13 | /** 14 | * {@link java.io.InputStream} implementation that will always read one byte 15 | * less than the length specified in a {@link InputStream#read(byte[], int, int)} 16 | * method invocation. 17 | * 18 | * @author Elijah Zupancic 19 | * @since 3.1.1 20 | */ 21 | public class IncompleteByteReadInputStream extends InputStream { 22 | private final InputStream wrapped; 23 | 24 | public IncompleteByteReadInputStream(final InputStream wrapped) { 25 | this.wrapped = wrapped; 26 | } 27 | 28 | @Override 29 | public int read() throws IOException { 30 | return wrapped.read(); 31 | } 32 | 33 | @Override 34 | public int read(final byte[] b) throws IOException { 35 | return read(b, 0, b.length); 36 | } 37 | 38 | @Override 39 | public int read(byte[] b, int off, int len) throws IOException { 40 | if (len > 1 && len - off - 1 > 0) { 41 | return wrapped.read(b, off, len - 1); 42 | } else { 43 | return wrapped.read(b, off, len); 44 | } 45 | } 46 | 47 | @Override 48 | public void close() throws IOException { 49 | wrapped.close(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/client/crypto/LocallyIllegalAesCipherDetailsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.crypto; 9 | 10 | import org.testng.annotations.Test; 11 | 12 | public class LocallyIllegalAesCipherDetailsTest { 13 | 14 | @Test(expectedExceptions = Error.class, 15 | expectedExceptionsMessageRegExp = "This cipher is not compatible with the current runtime: .*") 16 | public void throwsUncheckedErrorsForAnyMethodCall() { 17 | // keyLengthBits passed here is for error reporting, no validation is applied 18 | LocallyIllegalAesCipherDetails illegalAesCipherDetails = new LocallyIllegalAesCipherDetails(0); 19 | 20 | illegalAesCipherDetails.getCipher(); // or any other method call from the SupportedCipherDetails interface 21 | } 22 | } -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/client/jobs/MantaJobPhaseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.jobs; 9 | 10 | import org.testng.annotations.Test; 11 | 12 | /** 13 | * Tests the behavior of the validations and accessors of {@link MantaJobPhase} 14 | * instance. 15 | * 16 | * @author Elijah Zupancic 17 | */ 18 | public class MantaJobPhaseTest { 19 | 20 | @Test 21 | public void canCreateMapPhase() { 22 | new MantaJobPhase().setType("map"); 23 | } 24 | 25 | @Test 26 | public void canCreateReducePhase() { 27 | new MantaJobPhase().setType("reduce"); 28 | } 29 | 30 | @Test(expectedExceptions = IllegalArgumentException.class) 31 | public void cantCreateUnknownPhase() { 32 | new MantaJobPhase().setType("anything else"); 33 | } 34 | 35 | @Test 36 | public void canSetCountForReduce() { 37 | new MantaJobPhase() 38 | .setType("reduce") 39 | .setCount(2); 40 | } 41 | 42 | @Test(expectedExceptions = IllegalArgumentException.class) 43 | public void cantSetCountForMapPhase() { 44 | new MantaJobPhase() 45 | .setType("map") 46 | .setCount(2); 47 | } 48 | 49 | @Test(expectedExceptions = IllegalArgumentException.class) 50 | public void cantSetBadCountValue() { 51 | new MantaJobPhase() 52 | .setCount(0); 53 | } 54 | 55 | @Test(expectedExceptions = IllegalArgumentException.class) 56 | public void cantSetBadMemoryValue() { 57 | new MantaJobPhase() 58 | .setMemory(0); 59 | } 60 | 61 | @Test(expectedExceptions = IllegalArgumentException.class) 62 | public void cantSetBadDiskValue() { 63 | new MantaJobPhase() 64 | .setDisk(0); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/client/jobs/MantaJobTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.jobs; 9 | 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * Tests the behavior of the validations and accessors of {@link MantaJob} 18 | * instance. 19 | * 20 | * @author Elijah Zupancic 21 | */ 22 | public class MantaJobTest { 23 | @Test 24 | public void canGetMapPhases() { 25 | MantaJobPhase phase1 = new MantaJobPhase().setType("map").setExec("echo 1"); 26 | MantaJobPhase phase2 = new MantaJobPhase().setType("map").setExec("echo 2"); 27 | MantaJobPhase phase3 = new MantaJobPhase().setType("reduce").setExec("echo 3"); 28 | List phases = new ArrayList<>(); 29 | phases.add(phase1); 30 | phases.add(phase2); 31 | phases.add(phase3); 32 | 33 | MantaJob job = new MantaJob("test job", phases); 34 | 35 | List mapPhases = job.getMapPhases(); 36 | 37 | Assert.assertEquals(mapPhases.get(0), phase1); 38 | Assert.assertEquals(mapPhases.get(1), phase2); 39 | } 40 | 41 | @Test 42 | public void canGetReducePhases() { 43 | MantaJobPhase phase1 = new MantaJobPhase().setType("map").setExec("echo 1"); 44 | MantaJobPhase phase2 = new MantaJobPhase().setType("map").setExec("echo 2"); 45 | MantaJobPhase phase3 = new MantaJobPhase().setType("reduce").setExec("echo 3"); 46 | MantaJobPhase phase4 = new MantaJobPhase().setType("reduce").setExec("echo 4"); 47 | 48 | List phases = new ArrayList<>(); 49 | phases.add(phase1); 50 | phases.add(phase2); 51 | phases.add(phase3); 52 | phases.add(phase4); 53 | 54 | MantaJob job = new MantaJob("test job", phases); 55 | 56 | List reducePhases = job.getReducePhases(); 57 | 58 | Assert.assertEquals(reducePhases.get(0), phase3); 59 | Assert.assertEquals(reducePhases.get(1), phase4); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/client/multipart/TestMultipartManagerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import org.apache.commons.io.FileUtils; 11 | import org.testng.Assert; 12 | import org.testng.annotations.Test; 13 | 14 | import java.io.IOException; 15 | import java.nio.charset.StandardCharsets; 16 | import java.util.stream.Stream; 17 | 18 | @Test 19 | public class TestMultipartManagerTest { 20 | MantaMultipartManager manager = new TestMultipartManager(); 21 | 22 | public void canDoMultipartUpload() throws IOException { 23 | TestMultipartUpload upload = manager.initiateUpload("/user/stor/testobject"); 24 | 25 | MantaMultipartUploadPart[] parts = new MantaMultipartUploadPart[] { 26 | manager.uploadPart(upload, 1, "Line 1\n"), 27 | manager.uploadPart(upload, 2, "Line 2\n"), 28 | manager.uploadPart(upload, 3, "Line 3\n"), 29 | manager.uploadPart(upload, 4, "Line 4\n"), 30 | manager.uploadPart(upload, 5, "Line 5") 31 | }; 32 | 33 | Stream partsStream = Stream.of(parts); 34 | 35 | manager.complete(upload, partsStream); 36 | 37 | String actual = FileUtils.readFileToString(upload.getContents(), 38 | StandardCharsets.UTF_8); 39 | 40 | String expected = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5"; 41 | 42 | Assert.assertEquals(actual, expected); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/client/multipart/TestMultipartUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client.multipart; 9 | 10 | import java.io.File; 11 | import java.util.UUID; 12 | 13 | public class TestMultipartUpload extends AbstractMultipartUpload { 14 | private final File partsDirectory; 15 | private final File destinationDirectory; 16 | private final File metadata; 17 | private final File headers; 18 | private final File contents; 19 | private final Long contentLength; 20 | 21 | public TestMultipartUpload(UUID uploadId, 22 | String path, 23 | Long contentLength, 24 | File partsDirectory, 25 | File destinationDirectory, 26 | File metadata, File headers, 27 | File contents) { 28 | super(uploadId, path); 29 | this.contentLength = contentLength; 30 | this.partsDirectory = partsDirectory; 31 | this.destinationDirectory = destinationDirectory; 32 | this.metadata = metadata; 33 | this.headers = headers; 34 | this.contents = contents; 35 | } 36 | 37 | public File getMetadata() { 38 | return metadata; 39 | } 40 | 41 | public File getHeaders() { 42 | return headers; 43 | } 44 | 45 | public File getContents() { 46 | return contents; 47 | } 48 | 49 | public Long getContentLength() { 50 | return contentLength; 51 | } 52 | 53 | public File getPartsPath() { 54 | return new File(partsDirectory.getPath() + 55 | File.separator + getId()); 56 | } 57 | 58 | public File getDestinationPath() { 59 | return new File(destinationDirectory + File.separator + getPath()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/config/MantaClientMetricConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.config; 9 | 10 | import com.codahale.metrics.MetricRegistry; 11 | import org.testng.Assert; 12 | import org.testng.annotations.Test; 13 | 14 | import java.util.UUID; 15 | 16 | @Test 17 | public class MantaClientMetricConfigurationTest { 18 | public void rejectsInvalidInputs() throws Exception { 19 | Assert.assertThrows(NullPointerException.class, () -> 20 | new MantaClientMetricConfiguration(null, null)); 21 | Assert.assertThrows(NullPointerException.class, () -> 22 | new MantaClientMetricConfiguration(null, null, null, null)); 23 | 24 | Assert.assertThrows(NullPointerException.class, () -> 25 | new MantaClientMetricConfiguration(UUID.randomUUID(), new MetricRegistry(), MetricReporterMode.SLF4J, null)); 26 | 27 | Assert.assertThrows(IllegalArgumentException.class, () -> 28 | new MantaClientMetricConfiguration(UUID.randomUUID(), new MetricRegistry(), MetricReporterMode.SLF4J, -1)); 29 | 30 | Assert.assertThrows(IllegalArgumentException.class, () -> 31 | new MantaClientMetricConfiguration(UUID.randomUUID(), new MetricRegistry(), MetricReporterMode.SLF4J, 0)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/exception/ConfigurationExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | import com.joyent.manta.util.MantaVersion; 11 | import org.testng.Assert; 12 | import org.testng.annotations.Test; 13 | 14 | @Test 15 | public class ConfigurationExceptionTest { 16 | public void containsMantaVersionContext() { 17 | ConfigurationException e = new ConfigurationException(); 18 | String sdkVersion = e.getContextValues("mantaSdkVersion").get(0).toString(); 19 | Assert.assertNotNull(sdkVersion, 20 | "SDK version data should be in exception context"); 21 | Assert.assertEquals(sdkVersion, MantaVersion.VERSION, 22 | "SDK version should equal value coded"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/exception/MantaChecksumFailedExceptionTest.java: -------------------------------------------------------------------------------- 1 | package com.joyent.manta.exception; 2 | 3 | import com.joyent.manta.http.MantaHttpHeaders; 4 | import com.joyent.manta.util.MantaVersion; 5 | import org.apache.http.*; 6 | import org.apache.http.client.methods.HttpPut; 7 | import org.apache.http.impl.DefaultHttpResponseFactory; 8 | import org.apache.http.message.BasicStatusLine; 9 | import org.testng.Assert; 10 | import org.testng.annotations.Test; 11 | 12 | import java.net.URI; 13 | import java.net.URISyntaxException; 14 | import java.util.UUID; 15 | 16 | /** 17 | * Created by tomascelaya on 6/28/17. 18 | */ 19 | public class MantaChecksumFailedExceptionTest { 20 | 21 | @Test 22 | public void containsExpectedFields() throws URISyntaxException { 23 | String dummyRequestId = UUID.randomUUID().toString(); 24 | String dummyUri = "http://test.manta.io/account/file"; 25 | 26 | HttpRequest request = new HttpPut(new URI(dummyUri)); 27 | HttpResponse response = DefaultHttpResponseFactory.INSTANCE.newHttpResponse( 28 | new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_NO_CONTENT, null), null); 29 | 30 | // requestId is extracted from the response, not the request 31 | response.setHeader(MantaHttpHeaders.REQUEST_ID, dummyRequestId); 32 | 33 | MantaChecksumFailedException e = new MantaChecksumFailedException("", request, response); 34 | 35 | Assert.assertEquals(e.getFirstContextValue("requestId"), dummyRequestId); 36 | Assert.assertEquals(e.getFirstContextValue("requestURL"), dummyUri); 37 | Assert.assertEquals(e.getFirstContextValue("responseStatusCode"), HttpStatus.SC_NO_CONTENT); 38 | 39 | String sdkVersion = e.getContextValues("mantaSdkVersion").get(0).toString(); 40 | Assert.assertNotNull(sdkVersion, 41 | "SDK version data should be in exception context"); 42 | Assert.assertEquals(sdkVersion, MantaVersion.VERSION, 43 | "SDK version should equal value coded"); 44 | } 45 | 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/exception/MantaErrorCodeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2019, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | import static com.joyent.manta.exception.MantaErrorCode.UNKNOWN_ERROR; 14 | import static com.joyent.manta.exception.MantaErrorCode.SSL_REQUIRED_ERROR; 15 | import static com.joyent.manta.exception.MantaErrorCode.NO_CODE_ERROR; 16 | import static com.joyent.manta.exception.MantaErrorCode.INVALID_LIMIT_ERROR; 17 | import static com.joyent.manta.exception.MantaErrorCode.NO_API_SERVERS_AVAILABLE; 18 | import static com.joyent.manta.exception.MantaErrorCode.OBJECT_NOT_FOUND_ERROR; 19 | import static com.joyent.manta.exception.MantaErrorCode.ROOT_DIRECTORY_ERROR; 20 | 21 | /** 22 | * Tests the behavior of the {@link MantaErrorCode} enumeration. 23 | * 24 | * @author Elijah Zupancic 25 | * @author Ashwin A Nair 26 | */ 27 | @Test 28 | public class MantaErrorCodeTest { 29 | public void valueOfCodeCanFindByMatchingCode() { 30 | final MantaErrorCode actualLimitError = MantaErrorCode.valueOfCode("InvalidLimit"); 31 | final MantaErrorCode actualNoApiError = MantaErrorCode.valueOfCode("NoApiServersAvailable"); 32 | final MantaErrorCode actualObjectNotFoundError = MantaErrorCode.valueOfCode("ObjectNotFoundError"); 33 | 34 | Assert.assertEquals(actualLimitError, INVALID_LIMIT_ERROR); 35 | Assert.assertEquals(actualNoApiError, NO_API_SERVERS_AVAILABLE); 36 | Assert.assertEquals(actualObjectNotFoundError, OBJECT_NOT_FOUND_ERROR); 37 | } 38 | 39 | public void valueOfCodeCanFindByNonmatching() { 40 | final MantaErrorCode actual = MantaErrorCode.valueOfCode("Who knows?"); 41 | 42 | Assert.assertEquals(actual, UNKNOWN_ERROR); 43 | } 44 | 45 | public void valueOfCodeCanFindByNull() { 46 | final MantaErrorCode actual = MantaErrorCode.valueOfCode(null); 47 | 48 | Assert.assertEquals(actual, NO_CODE_ERROR); 49 | } 50 | 51 | @SuppressWarnings("deprecation") 52 | public void valueOfCodeCanFindInDeprectaedErrors() { 53 | final MantaErrorCode actualSslError = MantaErrorCode.valueOfCode("SSLRequired"); 54 | final MantaErrorCode actualRootDirectoryError = MantaErrorCode.valueOfCode("RootDirectory"); 55 | 56 | Assert.assertEquals(actualSslError, SSL_REQUIRED_ERROR); 57 | Assert.assertEquals(actualRootDirectoryError, ROOT_DIRECTORY_ERROR); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/exception/MantaExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | import com.joyent.manta.util.MantaVersion; 11 | import org.testng.Assert; 12 | import org.testng.annotations.Test; 13 | 14 | @Test 15 | public class MantaExceptionTest { 16 | public void containsMantaVersionContext() { 17 | MantaException e = new MantaException(); 18 | String sdkVersion = e.getContextValues("mantaSdkVersion").get(0).toString(); 19 | Assert.assertNotNull(sdkVersion, 20 | "SDK version data should be in exception context"); 21 | Assert.assertEquals(sdkVersion, MantaVersion.VERSION, 22 | "SDK version should equal value coded"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/exception/MantaIOExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | import com.joyent.manta.util.MantaVersion; 11 | import org.testng.Assert; 12 | import org.testng.annotations.Test; 13 | 14 | @Test 15 | public class MantaIOExceptionTest { 16 | public void containsMantaVersionContext() { 17 | MantaIOException e = new MantaIOException(); 18 | String sdkVersion = e.getContextValues("mantaSdkVersion").get(0).toString(); 19 | Assert.assertNotNull(sdkVersion, 20 | "SDK version data should be in exception context"); 21 | Assert.assertEquals(sdkVersion, MantaVersion.VERSION, 22 | "SDK version should equal value coded"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/exception/OnCloseAggregateExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.exception; 9 | 10 | import com.joyent.manta.util.MantaVersion; 11 | import org.testng.Assert; 12 | import org.testng.annotations.Test; 13 | 14 | @Test 15 | public class OnCloseAggregateExceptionTest { 16 | public void containsMantaVersionContext() { 17 | OnCloseAggregateException e = new OnCloseAggregateException(); 18 | String sdkVersion = e.getContextValues("mantaSdkVersion").get(0).toString(); 19 | Assert.assertNotNull(sdkVersion, 20 | "SDK version data should be in exception context"); 21 | Assert.assertEquals(sdkVersion, MantaVersion.VERSION, 22 | "SDK version should equal value coded"); 23 | } 24 | public void canAggregateExceptions() { 25 | String msg = "Exception message"; 26 | OnCloseAggregateException exception = new OnCloseAggregateException(msg); 27 | 28 | for (int i = 1; i < 11; i++) { 29 | Exception inner = new RuntimeException("Exception " + i); 30 | exception.aggregateException(inner); 31 | } 32 | 33 | int entries = exception.getContextEntries().size(); 34 | Assert.assertEquals(entries, 11); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/http/ApacheHttpTestUtils.java: -------------------------------------------------------------------------------- 1 | package com.joyent.manta.http; 2 | 3 | import org.apache.http.Header; 4 | import org.apache.http.HttpMessage; 5 | import org.apache.http.HttpResponse; 6 | import org.apache.http.HttpVersion; 7 | import org.apache.http.client.methods.HttpGet; 8 | import org.apache.http.message.BasicHeader; 9 | import org.apache.http.message.BasicRequestLine; 10 | 11 | import java.util.Map; 12 | 13 | import static org.mockito.ArgumentMatchers.anyString; 14 | import static org.mockito.Mockito.mock; 15 | import static org.mockito.Mockito.when; 16 | 17 | public final class ApacheHttpTestUtils { 18 | 19 | private ApacheHttpTestUtils() { 20 | } 21 | 22 | static Header[] singleValueHeaderList(final String name, final String value) { 23 | return new Header[]{new BasicHeader(name, value)}; 24 | } 25 | 26 | static HttpGet prepareRequestWithHeaders(final Map headers) { 27 | final HttpGet req = prepareMessageWithHeaders(HttpGet.class, headers); 28 | 29 | when(req.getRequestLine()).thenReturn(new BasicRequestLine(HttpGet.METHOD_NAME, "", HttpVersion.HTTP_1_1)); 30 | 31 | return req; 32 | } 33 | 34 | static HttpResponse prepareResponseWithHeaders(final Map headers) { 35 | return prepareMessageWithHeaders(HttpResponse.class, headers); 36 | } 37 | 38 | static T prepareMessageWithHeaders(final Class klass, 39 | final Map headers) { 40 | final T msg = mock(klass); 41 | 42 | // return an empty list unless a list of headers was provided 43 | when(msg.getHeaders(anyString())).then(invocation -> { 44 | final String headerName = invocation.getArgument(0); 45 | return headers.getOrDefault(headerName, new Header[0]); 46 | }); 47 | 48 | when(msg.getFirstHeader(anyString())).then(invocation -> { 49 | final String headerName = invocation.getArgument(0); 50 | if (!headers.containsKey(headerName)) { 51 | return null; 52 | } 53 | 54 | final Header[] matched = headers.get(headerName); 55 | if (matched.length == 0) { 56 | return null; 57 | } 58 | 59 | return matched[0]; 60 | }); 61 | 62 | for (final Map.Entry headerNameAndList : headers.entrySet()) { 63 | final String headerName = headerNameAndList.getKey(); 64 | when(msg.getHeaders(headerName)).thenReturn(headerNameAndList.getValue()); 65 | } 66 | 67 | return msg; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/http/FakeCloseableHttpClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import org.apache.http.HttpHost; 11 | import org.apache.http.HttpRequest; 12 | import org.apache.http.client.methods.CloseableHttpResponse; 13 | import org.apache.http.impl.client.CloseableHttpClient; 14 | import org.apache.http.protocol.HttpContext; 15 | 16 | import java.io.IOException; 17 | 18 | /** 19 | * Class that allows you to fake a HTTP client by preemptively inserting a 20 | * response object. 21 | */ 22 | public class FakeCloseableHttpClient extends CloseableHttpClient { 23 | final CloseableHttpResponse response; 24 | 25 | public FakeCloseableHttpClient(final CloseableHttpResponse response) { 26 | this.response = response; 27 | } 28 | 29 | @Override 30 | protected CloseableHttpResponse doExecute(HttpHost target, 31 | HttpRequest request, 32 | HttpContext context) 33 | throws IOException { 34 | return response; 35 | } 36 | 37 | @Override 38 | public void close() throws IOException { 39 | } 40 | 41 | @Deprecated 42 | @Override 43 | public org.apache.http.params.HttpParams getParams() { 44 | return null; 45 | } 46 | 47 | @Deprecated 48 | @Override 49 | public org.apache.http.conn.ClientConnectionManager getConnectionManager() { 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/http/MantaConnectionFactoryConfiguratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http; 9 | 10 | import org.mockito.Mockito; 11 | import org.mockito.MockitoAnnotations; 12 | import org.testng.Assert; 13 | import org.testng.annotations.AfterMethod; 14 | import org.testng.annotations.BeforeMethod; 15 | import org.testng.annotations.Test; 16 | 17 | import java.io.IOException; 18 | 19 | @Test 20 | public class MantaConnectionFactoryConfiguratorTest { 21 | 22 | @BeforeMethod 23 | public void setup() throws IOException { 24 | MockitoAnnotations.initMocks(this); 25 | } 26 | 27 | @AfterMethod 28 | public void tearDown() throws IOException { 29 | Mockito.validateMockitoUsage(); 30 | } 31 | 32 | public void willValidateInputs() { 33 | Assert.assertThrows(() -> new MantaConnectionFactoryConfigurator(null)); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/http/MantaHttpRequestRetryHandlerTest.java: -------------------------------------------------------------------------------- 1 | package com.joyent.manta.http; 2 | 3 | import com.codahale.metrics.Meter; 4 | import com.codahale.metrics.MetricFilter; 5 | import com.codahale.metrics.MetricRegistry; 6 | import com.joyent.manta.config.MantaClientMetricConfiguration; 7 | import org.apache.http.client.protocol.HttpClientContext; 8 | import org.testng.annotations.Test; 9 | 10 | import java.io.IOException; 11 | import java.util.Collection; 12 | import java.util.Optional; 13 | import java.util.UUID; 14 | 15 | import static org.testng.Assert.assertEquals; 16 | import static org.testng.Assert.assertTrue; 17 | 18 | @Test 19 | public class MantaHttpRequestRetryHandlerTest { 20 | 21 | private static final MetricFilter FILTER_RETRY_METRIC = (name, metric) -> name.equals("retries"); 22 | 23 | public void indicatesShouldRetryOnGenericIOException() { 24 | final MantaHttpRequestRetryHandler retryHandler = new MantaHttpRequestRetryHandler(1); 25 | 26 | assertTrue(retryHandler.retryRequest(new IOException("something went wrong"), 1, new HttpClientContext())); 27 | } 28 | 29 | public void createsRetriesMetricInRegistry() { 30 | final MetricRegistry registry = new MetricRegistry(); 31 | final UUID id = new UUID(0L, 1L); 32 | 33 | /* Registration of the registry is a side-effect of creating a new handler. 34 | * In order for this test to run successfully, this instance *must* be created. */ 35 | new MantaHttpRequestRetryHandler(0, new MantaClientMetricConfiguration(id, registry)); 36 | 37 | final Collection meters = registry.getMeters(FILTER_RETRY_METRIC).values(); 38 | assertEquals(meters.size(), 1); 39 | } 40 | 41 | @Test(dependsOnMethods = {"indicatesShouldRetryOnGenericIOException", "createsRetriesMetricInRegistry"}) 42 | public void recordsRetryMetric() { 43 | final MetricRegistry registry = new MetricRegistry(); 44 | final MantaHttpRequestRetryHandler retryHandler = new MantaHttpRequestRetryHandler(1, new MantaClientMetricConfiguration(UUID.randomUUID(), registry)); 45 | 46 | final Optional maybeMeter = registry.getMeters(FILTER_RETRY_METRIC).values().stream().findFirst(); 47 | assertTrue(maybeMeter.isPresent()); 48 | 49 | assertEquals(maybeMeter.get().getCount(), 0, "meter should have zero samples"); 50 | 51 | retryHandler.retryRequest(new IOException("something went wrong"), 1, new HttpClientContext()); 52 | assertEquals(maybeMeter.get().getCount(), 1, "meter should have one sample"); 53 | 54 | retryHandler.retryRequest(new IOException("something else went wrong"), 1, new HttpClientContext()); 55 | assertEquals(maybeMeter.get().getCount(), 2, "meter should have two samples"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/http/entity/DigestedEntityTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http.entity; 9 | 10 | import com.twmacinta.util.FastMD5Digest; 11 | import org.apache.commons.text.CharacterPredicates; 12 | import org.apache.commons.text.RandomStringGenerator; 13 | import org.testng.Assert; 14 | import org.testng.annotations.Test; 15 | 16 | import java.io.ByteArrayOutputStream; 17 | import java.nio.charset.StandardCharsets; 18 | import java.util.Arrays; 19 | 20 | @Test 21 | public class DigestedEntityTest { 22 | private static final RandomStringGenerator STRING_GENERATOR = 23 | new RandomStringGenerator.Builder() 24 | .filteredBy(CharacterPredicates.LETTERS) 25 | .build(); 26 | 27 | public void testWriteToProducesReliableDigest() throws Exception { 28 | String content = STRING_GENERATOR.generate(100); 29 | DigestedEntity entity = new DigestedEntity( 30 | new ExposedStringEntity(content, StandardCharsets.UTF_8), 31 | new FastMD5Digest()); 32 | 33 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 34 | entity.writeTo(out); 35 | byte[] initialDigest = entity.getDigest(); 36 | 37 | // connection reset, httpclient performs a retry reusing the same entity 38 | out.reset(); 39 | entity.writeTo(out); 40 | byte[] retryDigest = entity.getDigest(); 41 | 42 | Assert.assertTrue( 43 | Arrays.equals(initialDigest, retryDigest), 44 | "Reuse of DigestedEntity produced differing digest for first retry"); 45 | 46 | // connection reset again 47 | out.reset(); 48 | entity.writeTo(out); 49 | byte[] extraRetryDigest = entity.getDigest(); 50 | 51 | Assert.assertTrue( 52 | Arrays.equals(initialDigest, extraRetryDigest), 53 | "Reuse of DigestedEntity produced differing digest for second retry"); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/http/entity/ExposedStringEntityTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.http.entity; 9 | 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | import java.nio.charset.StandardCharsets; 14 | 15 | @Test 16 | public class ExposedStringEntityTest { 17 | public void canSetContentLength() { 18 | final String string = "I am a string"; 19 | ExposedStringEntity entity = new ExposedStringEntity(string, StandardCharsets.US_ASCII); 20 | 21 | Assert.assertEquals(entity.getContentLength(), 22 | string.length(), "String length should equal content-length"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/util/AutoContinuingInputStreamTest.java: -------------------------------------------------------------------------------- 1 | package com.joyent.manta.util; 2 | 3 | import org.apache.commons.io.IOUtils; 4 | import org.apache.commons.io.input.ClosedInputStream; 5 | import org.apache.commons.io.input.ProxyInputStream; 6 | import org.testng.annotations.Test; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | 11 | import static org.mockito.ArgumentMatchers.anyLong; 12 | import static org.mockito.ArgumentMatchers.same; 13 | import static org.mockito.Mockito.mock; 14 | import static org.mockito.Mockito.when; 15 | import static org.testng.Assert.assertEquals; 16 | import static org.testng.Assert.assertSame; 17 | import static org.testng.Assert.expectThrows; 18 | 19 | @Test 20 | public class AutoContinuingInputStreamTest { 21 | 22 | /** 23 | * We can't use {@link org.apache.commons.io.input.BrokenInputStream} for this test because it will return the same 24 | * exception during close and trigger the 25 | * self-suppression 26 | * issue. 27 | *

28 | * On the other hand, we can't use {@link FailingInputStream} because that generates its own exceptions, so we 29 | * wouldn't be able to use {@link org.testng.Assert#assertSame} and check that no suppressed exceptions were added. 30 | */ 31 | private static final class ReadExceptionInputStream extends ProxyInputStream { 32 | 33 | private final IOException exception; 34 | 35 | public ReadExceptionInputStream(final IOException exception) { 36 | super(ClosedInputStream.CLOSED_INPUT_STREAM); 37 | this.exception = exception; 38 | } 39 | 40 | @Override 41 | protected void beforeRead(final int n) throws IOException { 42 | throw this.exception; 43 | } 44 | } 45 | 46 | public void rethrowsUnrecoverableExceptionsDirectly() throws Exception { 47 | // the exception to consider fatal 48 | final IOException ex = new IOException("oops"); 49 | 50 | // source stream always throws that exception 51 | final InputStream original = new ReadExceptionInputStream(ex); 52 | 53 | // pretend that it was a fatal exception and should be rethrown 54 | final InputStreamContinuator continuator = mock(InputStreamContinuator.class); 55 | when(continuator.buildContinuation(same(ex), anyLong())).thenThrow(ex); 56 | 57 | final IOException caught = expectThrows(IOException.class, () -> { 58 | try (final AutoContinuingInputStream in = new AutoContinuingInputStream(original, continuator)) { 59 | IOUtils.toByteArray(in); 60 | } 61 | }); 62 | 63 | assertSame(caught, ex); 64 | assertEquals(caught.getSuppressed().length, 0); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/util/FailingOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import java.io.IOException; 11 | import java.io.OutputStream; 12 | import java.util.concurrent.atomic.AtomicLong; 13 | 14 | public class FailingOutputStream extends OutputStream { 15 | 16 | public static final int NO_FAILURE = -1; 17 | 18 | /** 19 | * The wrapped InputStream 20 | */ 21 | private final OutputStream wrapped; 22 | 23 | /** 24 | * Current read byte count. 25 | */ 26 | private final AtomicLong count = new AtomicLong(0L); 27 | 28 | /** 29 | * Minimum number of bytes to read before failing. 30 | */ 31 | private long minimumBytes; 32 | 33 | public FailingOutputStream(final OutputStream wrapped, int minimumBytes) { 34 | this.wrapped = wrapped; 35 | this.minimumBytes = minimumBytes; 36 | } 37 | 38 | @Override 39 | public void write(int b) throws IOException { 40 | failAfterMinimum(1); 41 | count.incrementAndGet(); 42 | wrapped.write(b); 43 | } 44 | 45 | @Override 46 | public void write(byte[] bytes) throws IOException { 47 | write(bytes, 0, bytes.length); 48 | } 49 | 50 | @Override 51 | public void write(byte[] bytes, int off, int len) throws IOException { 52 | failAfterMinimum(bytes.length); 53 | count.addAndGet(bytes.length); 54 | wrapped.write(bytes, off, len); 55 | } 56 | 57 | public void setMinimumBytes(final int minimumBytes) { 58 | this.minimumBytes = minimumBytes; 59 | } 60 | 61 | private void failAfterMinimum(final int next) throws IOException { 62 | if (minimumBytes == NO_FAILURE) { 63 | return; 64 | } 65 | 66 | if (count.get() + next > minimumBytes) { 67 | throw new IOException("Write failure after byte " + minimumBytes); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/util/FileInputStreamContinuator.java: -------------------------------------------------------------------------------- 1 | package com.joyent.manta.util; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | 8 | public class FileInputStreamContinuator implements InputStreamContinuator { 9 | 10 | private final File file; 11 | 12 | public FileInputStreamContinuator(final File file) { 13 | this.file = file; 14 | } 15 | 16 | @Override 17 | public InputStream buildContinuation(final IOException ex, final long bytesRead) throws IOException { 18 | 19 | final FileInputStream fileStream = new FileInputStream(this.file); 20 | 21 | long skipRemaining = bytesRead; 22 | do { 23 | skipRemaining -= fileStream.skip(bytesRead); 24 | } while (0 < skipRemaining); 25 | 26 | return fileStream; 27 | } 28 | 29 | @Override 30 | public void close() { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/joyent/manta/util/MantaVersionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.util; 9 | 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | @Test 14 | public class MantaVersionTest { 15 | public void canLoadVersion() { 16 | Assert.assertNotNull(MantaVersion.VERSION); 17 | } 18 | 19 | public void canLoadVersionDate() { 20 | Assert.assertNotNull(MantaVersion.DATE); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/java/com/twmacinta/util/FastMD5DigestTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.twmacinta.util; 9 | 10 | import org.testng.Assert; 11 | import org.testng.AssertJUnit; 12 | import org.testng.annotations.Test; 13 | 14 | /** 15 | * @author Elijah Zupancic 16 | * @since 3.0.0 17 | */ 18 | @Test 19 | public class FastMD5DigestTest { 20 | public void canSaveAndLoadEncodedState() { 21 | final MD5State initialState = new MD5State(); 22 | initialState.buffer = new byte[] { (byte)23, (byte)34, (byte)56 }; 23 | initialState.state = new int[] { 23423, -5, -33, 232323, Integer.MAX_VALUE }; 24 | initialState.count = 20123; 25 | 26 | final byte[] encodedState = FastMD5Digest.generateEncodedState(initialState); 27 | 28 | final MD5State decodedState = new MD5State(); 29 | FastMD5Digest.updateStateFromEncodedState(decodedState, encodedState); 30 | 31 | AssertJUnit.assertArrayEquals("MD5State buffer arrays do not match", 32 | initialState.buffer, decodedState.buffer); 33 | AssertJUnit.assertArrayEquals("MD5State state arrays do not match", 34 | initialState.state, decodedState.state); 35 | Assert.assertEquals(decodedState.count, initialState.count, 36 | "MD5State count value was decoded correctly"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | [%thread] %-5level %logger - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/chaucer.txt: -------------------------------------------------------------------------------- 1 | A SERGEANT OF THE LAW, wary and wise, That often had y-been at the Parvis, <26> There was also, full rich of excellence. Discreet he was, and of great reverence: He seemed such, his wordes were so wise, Justice he was full often in assize, By patent, and by plein* commission; For his science, and for his high renown, Of fees and robes had he many one. So great a purchaser was nowhere none. All was fee simple to him, in effect His purchasing might not be in suspect* Nowhere so busy a man as he there was And yet he seemed busier than he was In termes had he case' and doomes* all That from the time of King Will. were fall. Thereto he could indite, and make a thing There coulde no wight *pinch at* his writing. And every statute coud* he plain by rote He rode but homely in a medley* coat, Girt with a seint* of silk, with barres small; Of his array tell I no longer tale. 2 | 3 | A FRANKELIN was in this company; White was his beard, as is the daisy. Of his complexion he was sanguine. Well lov'd he in the morn a sop in wine. To liven in delight was ever his won, For he was Epicurus' owen son, That held opinion, that plein delight Was verily felicity perfite. An householder, and that a great, was he; Saint Julian he was in his country. His bread, his ale, was alway after one; A better envined man was nowhere none; Withoute bake-meat never was his house, Of fish and flesh, and that so plenteous, It snowed in his house of meat and drink, Of alle dainties that men coulde think. After the sundry seasons of the year, So changed he his meat and his soupere. Full many a fat partridge had he in mew, And many a bream, and many a luce in stew Woe was his cook, but if his sauce were Poignant and sharp, and ready all his gear. His table dormant in his hall alway Stood ready cover'd all the longe day. At sessions there was he lord and sire. Full often time he was knight of the shire An anlace, and a gipciere all of silk, Hung at his girdle, white as morning milk. A sheriff had he been, and a countour Was nowhere such a worthy vavasour. 4 | 5 | An HABERDASHER, and a CARPENTER, A WEBBE, a DYER, and a TAPISER, Were with us eke, cloth'd in one livery, Of a solemn and great fraternity. Full fresh and new their gear y-picked was. Their knives were y-chaped not with brass, But all with silver wrought full clean and well, Their girdles and their pouches every deal. Well seemed each of them a fair burgess, To sitten in a guild-hall, on the dais. Evereach, for the wisdom that he can, Was shapely for to be an alderman. For chattels hadde they enough and rent, And eke their wives would it well assent: And elles certain they had been to blame. It is full fair to be y-clep'd madame, And for to go to vigils all before, And have a mantle royally y-bore. 6 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-CBC-PKCS5Padding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-CBC-PKCS5Padding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-CBC-PKCS5Padding.headers: -------------------------------------------------------------------------------- 1 | etag: 465fbef5-4e01-4889-8b48-eb9077bcd86c 2 | last-modified: Sat, 29 Dec 2018 00:09:40 GMT 3 | m-encrypt-key-id: personal-256 4 | m-encrypt-plaintext-content-length: 2753 5 | m-encrypt-iv: OQFOzJAd3yPYxoXaQCA5og== 6 | m-encrypt-metadata: 9MyDXE6bwMrzZDc1BQ/AX8hVNqvSxQkG2xHkMVfO47NIfEAQB45ffMmM2dT5p29F 7 | m-encrypt-metadata-hmac: WlWFtM99bRHWvQv9L/9VtA== 8 | m-encrypt-type: client/1 9 | m-encrypt-cipher: AES128/CBC/PKCS5Padding 10 | m-encrypt-metadata-iv: q2tnbvo/d57bID+yDWQ1Rw== 11 | m-encrypt-hmac-type: HmacMD5 12 | durability-level: 2 13 | content-length: 2784 14 | content-md5: YY6wsZJo9SLUspDE35+KQA== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 00:23:54 GMT 17 | server: Manta 18 | x-request-id: 139e4472-d124-40ad-af42-f4aae04dc803 19 | x-response-time: 324 20 | x-server-name: 39adec6c-bded-4a14-9d80-5a8bfc1121f9 21 | connection: keep-alive 22 | x-request-received: 1546043033097 23 | x-request-processing-time: 1501 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-CTR-NoPadding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-CTR-NoPadding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-CTR-NoPadding.headers: -------------------------------------------------------------------------------- 1 | etag: 70b2ce45-1e4b-e3d6-967b-c41c43f3fd9e 2 | last-modified: Sat, 29 Dec 2018 00:09:35 GMT 3 | m-encrypt-key-id: personal-256 4 | m-encrypt-plaintext-content-length: 2753 5 | m-encrypt-iv: bAxP15L9P/wqiY0lDDmLWA== 6 | m-encrypt-metadata: 2jb4KSmaxgtvVAcJTZBa71Fg7kHDdNUoKj5TlUTi5mxVqTwFFCs0bdY= 7 | m-encrypt-metadata-hmac: GD9h5IRiWsVebWK/yOA3nA== 8 | m-encrypt-type: client/1 9 | m-encrypt-cipher: AES128/CTR/NoPadding 10 | m-encrypt-metadata-iv: cfW2bKmJwv8HY/gluw83/w== 11 | m-encrypt-hmac-type: HmacMD5 12 | durability-level: 2 13 | content-length: 2769 14 | content-md5: yKhsSqdgqIVkt3QukIK1fQ== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 00:27:39 GMT 17 | server: Manta 18 | x-request-id: fb271785-0ad8-4971-92ea-a0593177efaf 19 | x-response-time: 125 20 | x-server-name: 60771e58-2ad0-4c50-8b23-86b72f9307f8 21 | connection: keep-alive 22 | x-request-received: 1546043259008 23 | x-request-processing-time: 546 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-GCM-NoPadding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-GCM-NoPadding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES128-GCM-NoPadding.headers: -------------------------------------------------------------------------------- 1 | etag: 46d34b5c-bc0e-cf6a-834e-d3f930978266 2 | last-modified: Sat, 29 Dec 2018 00:09:22 GMT 3 | m-encrypt-metadata-aead-tag-length: 16 4 | m-encrypt-key-id: personal-256 5 | m-encrypt-aead-tag-length: 16 6 | m-encrypt-plaintext-content-length: 2753 7 | m-encrypt-iv: 2+94YlGJ2dIBwORuRJnH5Q== 8 | m-encrypt-metadata: WUZo5R1jm7k9h9xIg/r0MUZlpbc+aa8SYTGJv41br6Kyx0YRc/jtw3S9afsnwu8b3TEaetrDx77P 9 | m-encrypt-type: client/1 10 | m-encrypt-cipher: AES128/GCM/NoPadding 11 | m-encrypt-metadata-iv: Duo0t1c2xbF+venKvM8poQ== 12 | durability-level: 2 13 | content-length: 2769 14 | content-md5: 5bW53Bj3VoI1QYxGIFJc0w== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 00:53:04 GMT 17 | server: Manta 18 | x-request-id: 8ddfdbbe-53a9-495f-a07b-046e27c2e19a 19 | x-response-time: 22 20 | x-server-name: 1a1ff4e5-4e04-4e60-b993-689f95b67e89 21 | connection: keep-alive 22 | x-request-received: 1546044784239 23 | x-request-processing-time: 690 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-CBC-PKCS5Padding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-CBC-PKCS5Padding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-CBC-PKCS5Padding.headers: -------------------------------------------------------------------------------- 1 | etag: e7bffaf2-bb58-ca1f-e913-b45ebdb3b67d 2 | last-modified: Sat, 29 Dec 2018 00:09:42 GMT 3 | m-encrypt-key-id: personal-256 4 | m-encrypt-plaintext-content-length: 2753 5 | m-encrypt-iv: svYQNK0ZjNknNmOzQ3KA5A== 6 | m-encrypt-metadata: ltJEoctQAqFZzCK6CAt1YbZGQS2qsw/X043lsEiz9e6VRZ2dlCSrs7l92JVegH2T 7 | m-encrypt-metadata-hmac: gxNw68UrawFGruZFCNdQLg== 8 | m-encrypt-type: client/1 9 | m-encrypt-cipher: AES192/CBC/PKCS5Padding 10 | m-encrypt-metadata-iv: SDFsx1S61GKsPIb/6spVVg== 11 | m-encrypt-hmac-type: HmacMD5 12 | durability-level: 2 13 | content-length: 2784 14 | content-md5: 2MdETUSG49CTgv0sWf4ZWg== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 01:28:41 GMT 17 | server: Manta 18 | x-request-id: 87ffd628-ddf5-4c0c-99b8-70a43fab8363 19 | x-response-time: 129 20 | x-server-name: 4ff3f83e-23d3-49a0-986b-a6b0a881670b 21 | connection: keep-alive 22 | x-request-received: 1546046920285 23 | x-request-processing-time: 699 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-CTR-NoPadding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-CTR-NoPadding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-CTR-NoPadding.headers: -------------------------------------------------------------------------------- 1 | etag: 08c9ab1e-f10c-6423-9e84-c802eb416415 2 | last-modified: Sat, 29 Dec 2018 00:09:37 GMT 3 | m-encrypt-key-id: personal-256 4 | m-encrypt-plaintext-content-length: 2753 5 | m-encrypt-iv: /LkTFNbf/3Sy/TSLojfD5w== 6 | m-encrypt-metadata: wMee3+h/RujN7TVCYEkVfuiPvY5f/ODwz/uopmxX4ZC4Hyv+dm7Wf60= 7 | m-encrypt-metadata-hmac: AGqLoiAFZkDLIE9dNfZrHA== 8 | m-encrypt-type: client/1 9 | m-encrypt-cipher: AES192/CTR/NoPadding 10 | m-encrypt-metadata-iv: fWFo7DYIHyn+1laUmylaUg== 11 | m-encrypt-hmac-type: HmacMD5 12 | durability-level: 2 13 | content-length: 2769 14 | content-md5: jVulU+dWjJQTfPlJz1r3eQ== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 01:29:34 GMT 17 | server: Manta 18 | x-request-id: 8bd67721-25f8-46c0-b4b1-374186e6fca1 19 | x-response-time: 131 20 | x-server-name: 3d2b5d91-5cd9-4123-89a5-794f44eab9fd 21 | connection: keep-alive 22 | x-request-received: 1546046972803 23 | x-request-processing-time: 562 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-GCM-NoPadding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-GCM-NoPadding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES192-GCM-NoPadding.headers: -------------------------------------------------------------------------------- 1 | etag: b6f4def4-11d1-6a5b-8b62-f1ba08021f8f 2 | last-modified: Sat, 29 Dec 2018 00:09:31 GMT 3 | m-encrypt-metadata-aead-tag-length: 16 4 | m-encrypt-key-id: personal-256 5 | m-encrypt-aead-tag-length: 16 6 | m-encrypt-plaintext-content-length: 2753 7 | m-encrypt-iv: S2A5SIbKuHVN9u9CTZ/ZFg== 8 | m-encrypt-metadata: GLYQz86LwLNEy9glgaSV1HJcjdh/WOxej6sDad4iM1hDZ2+s/Qypbtt6hbAWFTLGGiNjsN2dexuN 9 | m-encrypt-type: client/1 10 | m-encrypt-cipher: AES192/GCM/NoPadding 11 | m-encrypt-metadata-iv: mTQHKnDnqHu/aX38ORkJOg== 12 | durability-level: 2 13 | content-length: 2769 14 | content-md5: ac6tJBTQ+SzQGOyS0FnCBg== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 01:30:52 GMT 17 | server: Manta 18 | x-request-id: 43d611ee-6557-4561-93b9-f252d3b299d5 19 | x-response-time: 126 20 | x-server-name: 60771e58-2ad0-4c50-8b23-86b72f9307f8 21 | connection: keep-alive 22 | x-request-received: 1546047050822 23 | x-request-processing-time: 704 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-CBC-PKCS5Padding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-CBC-PKCS5Padding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-CBC-PKCS5Padding.headers: -------------------------------------------------------------------------------- 1 | etag: cc1f9711-1a6c-4760-a5fe-a8bf1ef767ff 2 | last-modified: Sat, 29 Dec 2018 00:09:44 GMT 3 | m-encrypt-key-id: personal-256 4 | m-encrypt-plaintext-content-length: 2753 5 | m-encrypt-iv: pwZihz3tl+wJ4AulwTzeHw== 6 | m-encrypt-metadata: ZYXRgrOpoKKTC6WLd3iWOOrbolKahvKQPmxXUUrJTR07X7ea7I3Cq9lsUx4Ii+kg 7 | m-encrypt-metadata-hmac: l76Jhnz5/WCIWiT9qpOUFw== 8 | m-encrypt-type: client/1 9 | m-encrypt-cipher: AES256/CBC/PKCS5Padding 10 | m-encrypt-metadata-iv: gLW8OP/2iH3cavdqdX+cnw== 11 | m-encrypt-hmac-type: HmacMD5 12 | durability-level: 2 13 | content-length: 2784 14 | content-md5: gIdDyn0Y70W/gHIAIaQsTg== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 01:31:35 GMT 17 | server: Manta 18 | x-request-id: 14cc3868-32c7-4d64-897e-c1133441a7f8 19 | x-response-time: 141 20 | x-server-name: 39adec6c-bded-4a14-9d80-5a8bfc1121f9 21 | connection: keep-alive 22 | x-request-received: 1546047094438 23 | x-request-processing-time: 549 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-CTR-NoPadding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-CTR-NoPadding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-CTR-NoPadding.headers: -------------------------------------------------------------------------------- 1 | etag: 47b66755-1134-613c-fe17-df246e43ef28 2 | last-modified: Sat, 29 Dec 2018 00:09:38 GMT 3 | m-encrypt-key-id: personal-256 4 | m-encrypt-plaintext-content-length: 2753 5 | m-encrypt-iv: UmPLISH0nPqT66Qgv3DQZg== 6 | m-encrypt-metadata: 10kXzOcOK0/YUSiRHMxdXo3glrtGobfTvy0ioSUCO5d7BNpAAbcNSCs= 7 | m-encrypt-metadata-hmac: 9cS854aAzzIlZr0zDHG63w== 8 | m-encrypt-type: client/1 9 | m-encrypt-cipher: AES256/CTR/NoPadding 10 | m-encrypt-metadata-iv: h1RKHpVPsYHReCQoV8bqWQ== 11 | m-encrypt-hmac-type: HmacMD5 12 | durability-level: 2 13 | content-length: 2769 14 | content-md5: OcG0poeQCertMbicl8dX8Q== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 01:32:16 GMT 17 | server: Manta 18 | x-request-id: 23f9b496-43fa-4067-a0fe-ed28dbafb5c8 19 | x-response-time: 129 20 | x-server-name: 02d02889-cd80-4ac1-bc0c-4775b86661e4 21 | connection: keep-alive 22 | x-request-received: 1546047134767 23 | x-request-processing-time: 710 24 | 25 | -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-GCM-NoPadding.ciphertext: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-GCM-NoPadding.ciphertext -------------------------------------------------------------------------------- /java-manta-client-unshaded/src/test/resources/test-data/ciphertext/AES256-GCM-NoPadding.headers: -------------------------------------------------------------------------------- 1 | etag: e0dcd260-a18e-4115-fb13-cf56706dbb41 2 | last-modified: Sat, 29 Dec 2018 00:09:33 GMT 3 | m-encrypt-metadata-aead-tag-length: 16 4 | m-encrypt-key-id: personal-256 5 | m-encrypt-aead-tag-length: 16 6 | m-encrypt-plaintext-content-length: 2753 7 | m-encrypt-iv: DXayNmffopYsL2OeTuV78Q== 8 | m-encrypt-metadata: 0E0flhujrj8Uc0I7Pifym/J+tohCTVVDIk/7bVE1/JliJq6QsCH7nyVcsHXvLdvh7Ii8Qaa/AVKg 9 | m-encrypt-type: client/1 10 | m-encrypt-cipher: AES256/GCM/NoPadding 11 | m-encrypt-metadata-iv: 2NPIZa6CMSLOVd7NEg49bQ== 12 | durability-level: 2 13 | content-length: 2769 14 | content-md5: wWc8Pfer5ff7bqSXromWcA== 15 | content-type: application/octet-stream 16 | date: Sat, 29 Dec 2018 01:32:58 GMT 17 | server: Manta 18 | x-request-id: a8f59f2f-5596-405c-a5e6-f44e29c8180d 19 | x-response-time: 124 20 | x-server-name: 56564894-a7c2-470e-a218-3d859e7e1687 21 | connection: keep-alive 22 | x-request-received: 1546047176879 23 | x-request-processing-time: 533 24 | 25 | -------------------------------------------------------------------------------- /java-manta-examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | java-manta 12 | com.joyent.manta 13 | 3.5.1-SNAPSHOT 14 | 15 | 4.0.0 16 | 17 | java-manta-examples 18 | 19 | 20 | 21 | com.joyent.manta 22 | java-manta-client 23 | 3.5.1-SNAPSHOT 24 | compile 25 | 26 | 27 | org.apache.commons 28 | commons-lang3 29 | ${dependency.commons-lang.version} 30 | compile 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-checkstyle-plugin 40 | 41 | true 42 | 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-deploy-plugin 48 | ${maven-deploy-plugin.version} 49 | 50 | true 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /java-manta-examples/src/main/java/ClientEncryptionMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import com.joyent.manta.client.MantaClient; 10 | import com.joyent.manta.client.MantaMetadata; 11 | import com.joyent.manta.client.MantaObjectResponse; 12 | import com.joyent.manta.config.*; 13 | 14 | import java.util.Base64; 15 | import java.io.IOException; 16 | 17 | /* 18 | * Usage: set the mantaUserName, privateKeyPath, and publicKeyId with your own values. 19 | */ 20 | public class ClientEncryptionMetadata { 21 | 22 | public static void main(String... args) throws IOException { 23 | String mantaUserName = "USERNAME"; 24 | String privateKeyPath = "PATH/.ssh/id_rsa"; 25 | String publicKeyId = "04:92:7b:23:bc:08:4f:d7:3b:5a:38:9e:4a:17:2e:df"; 26 | 27 | ConfigContext config = new ChainedConfigContext( 28 | new DefaultsConfigContext(), 29 | new EnvVarConfigContext(), 30 | new MapConfigContext(System.getProperties())) 31 | .setMantaURL("https://us-east.manta.joyent.com") 32 | .setMantaUser(mantaUserName) 33 | .setMantaKeyPath(privateKeyPath) 34 | .setMantaKeyId(publicKeyId) 35 | .setClientEncryptionEnabled(true) 36 | .setEncryptionAlgorithm("AES256/CTR/NoPadding") 37 | .setEncryptionAuthenticationMode(EncryptionAuthenticationMode.Mandatory) 38 | .setPermitUnencryptedDownloads(false) 39 | .setEncryptionKeyId("simple/example") 40 | .setEncryptionPrivateKeyBytes(Base64.getDecoder().decode("RkZGRkZGRkJEOTY3ODNDNkM5MUUyMjIyMTExMTIyMjI=")); 41 | 42 | try (MantaClient client = new MantaClient(config)) { 43 | String mantaPath = MantaClient.SEPARATOR + mantaUserName + "/stor/meta"; 44 | 45 | MantaMetadata metadata = new MantaMetadata(); 46 | metadata.put("e-secretkey", "My Secret Value"); 47 | MantaObjectResponse putRes = client.put(mantaPath, "This is my secret message", metadata); 48 | 49 | System.out.println("HTTP PUT Response headers:"); 50 | System.out.println(putRes.getHttpHeaders().toString()); 51 | 52 | 53 | MantaObjectResponse getRes = client.get(mantaPath); 54 | MantaMetadata resMetadata = getRes.getMetadata(); 55 | 56 | System.out.println("Stored Metadata:"); 57 | System.out.println(resMetadata.get("e-secretkey")); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /java-manta-examples/src/main/java/DynamicAuthentication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import com.joyent.manta.client.MantaClient; 10 | import com.joyent.manta.config.AuthAwareConfigContext; 11 | import com.joyent.manta.config.BaseChainedConfigContext; 12 | import com.joyent.manta.config.ChainedConfigContext; 13 | import com.joyent.manta.config.DefaultsConfigContext; 14 | 15 | import java.io.IOException; 16 | import java.io.InputStream; 17 | import java.nio.charset.StandardCharsets; 18 | import java.util.Scanner; 19 | 20 | public class DynamicAuthentication { 21 | 22 | public static void main(String... args) throws IOException { 23 | 24 | // start with an unauthenticated user 25 | BaseChainedConfigContext config = new ChainedConfigContext( 26 | new DefaultsConfigContext()) 27 | .setMantaURL("https://us-east.manta.joyent.com") 28 | .setMantaUser("user/subuser") 29 | .setNoAuth(true); 30 | 31 | AuthAwareConfigContext authConfig = new AuthAwareConfigContext(config); 32 | 33 | try (MantaClient client = new MantaClient(authConfig)) { 34 | 35 | // read a public file 36 | String publicFile = "/user/public/foo"; 37 | String privateFile = "/user/stor/bar"; 38 | 39 | // Print out every line from file streamed real-time from Manta 40 | try (InputStream is = client.getAsInputStream(publicFile); 41 | Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name())) { 42 | 43 | while (scanner.hasNextLine()) { 44 | System.out.println(scanner.nextLine()); 45 | } 46 | } 47 | 48 | // enable authentication 49 | config.setNoAuth(false); 50 | config.setMantaUser("user"); 51 | config.setMantaKeyPath("src/test/java/data/id_rsa"); 52 | config.setMantaKeyId("04:92:7b:23:bc:08:4f:d7:3b:5a:38:9e:4a:17:2e:df"); 53 | authConfig.reload(); 54 | 55 | // Load file into memory as a string directly from Manta 56 | String publicData = client.getAsString(publicFile); 57 | System.out.println(publicData); 58 | 59 | // Load a file in the private home folder 60 | String privateData = client.getAsString(privateFile); 61 | System.out.println(privateData); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /java-manta-examples/src/main/java/JobsWithMantaJobBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import com.joyent.manta.client.MantaClient; 10 | import com.joyent.manta.client.jobs.MantaJobBuilder; 11 | import com.joyent.manta.client.jobs.MantaJobPhase; 12 | import com.joyent.manta.config.ConfigContext; 13 | import com.joyent.manta.config.SystemSettingsConfigContext; 14 | 15 | import java.io.IOException; 16 | import java.util.stream.Stream; 17 | 18 | /** 19 | * Creating a job using the MantaJobBuilder allows for a more fluent style of 20 | * job creation. Using this approach allows for a more fluent configuration of 21 | * job initialization. 22 | */ 23 | public class JobsWithMantaJobBuilder { 24 | public static void main(String... args) throws IOException { 25 | ConfigContext config = new SystemSettingsConfigContext(); 26 | MantaClient client = new MantaClient(config); 27 | 28 | // You can only get a builder from a MantaClient 29 | final MantaJobBuilder builder = client.jobBuilder(); 30 | 31 | MantaJobBuilder.Run runningJob = builder.newJob("example") 32 | .addInputs("/user/stor/logs/input_1", 33 | "/user/stor/logs/input_2", 34 | "/user/stor/logs/input_3", 35 | "/user/stor/logs/input_4") 36 | .addPhase(new MantaJobPhase() 37 | .setType("map") 38 | .setExec("grep foo")) 39 | .addPhase(new MantaJobPhase() 40 | .setType("reduce") 41 | .setExec("sort | uniq")) 42 | // This is an optional command that will validate that the inputs 43 | // specified are available 44 | .validateInputs() 45 | .run(); 46 | 47 | // This will wait until the job is finished 48 | MantaJobBuilder.Done finishedJob = runningJob.waitUntilDone() 49 | // This will validate if the job finished without errors. 50 | // If there was an error an exception will be thrown 51 | .validateJobsSucceeded(); 52 | 53 | // You will always need to close streams because we do everything online 54 | try (Stream outputs = finishedJob.outputs()) { 55 | // Print each output 56 | outputs.forEach(System.out::println); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /java-manta-examples/src/main/java/SimpleClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import com.joyent.manta.client.MantaClient; 10 | import com.joyent.manta.config.ChainedConfigContext; 11 | import com.joyent.manta.config.ConfigContext; 12 | import com.joyent.manta.config.DefaultsConfigContext; 13 | 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.nio.charset.StandardCharsets; 17 | import java.util.Scanner; 18 | 19 | public class SimpleClient { 20 | 21 | public static void main(String... args) throws IOException { 22 | ConfigContext config = new ChainedConfigContext( 23 | new DefaultsConfigContext()) 24 | .setMantaURL("https://us-east.manta.joyent.com") 25 | // If there is no subuser, then just use the account name 26 | .setMantaUser("user/subuser") 27 | .setMantaKeyPath("src/test/java/data/id_rsa") 28 | .setMantaKeyId("04:92:7b:23:bc:08:4f:d7:3b:5a:38:9e:4a:17:2e:df"); 29 | 30 | try (MantaClient client = new MantaClient(config)) { 31 | String mantaFile = "/user/stor/foo"; 32 | 33 | // Print out every line from file streamed real-time from Manta 34 | try (InputStream is = client.getAsInputStream(mantaFile); 35 | Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name())) { 36 | 37 | while (scanner.hasNextLine()) { 38 | System.out.println(scanner.nextLine()); 39 | } 40 | } 41 | 42 | // Load file into memory as a string directly from Manta 43 | String data = client.getAsString(mantaFile); 44 | System.out.println(data); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java-manta-it/src/.gitignore: -------------------------------------------------------------------------------- 1 | shade-workaround/ 2 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/manta/client/MantaClientAuthenticationIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client; 9 | 10 | import com.joyent.manta.config.*; 11 | import com.joyent.manta.exception.ConfigurationException; 12 | import org.testng.Assert; 13 | import org.testng.annotations.*; 14 | 15 | import java.io.IOException; 16 | import java.util.UUID; 17 | 18 | /** 19 | * Tests client authentication, sub-user functionality and other issues 20 | * associated with it for the {@link MantaClient} class. 21 | * 22 | * @author Ashwin A Nair- 23 | */ 24 | public class MantaClientAuthenticationIT { 25 | private static final String TEST_DATA = "Arise,Awake And Do Not Stop Until Your Goal Is Reached."; 26 | 27 | private MantaClient mantaClient; 28 | 29 | private String testPathPrefix; 30 | 31 | @BeforeClass 32 | @Parameters({"usingEncryption"}) 33 | public void beforeClass(@Optional Boolean usingEncryption) throws IOException { 34 | 35 | // Let TestNG configuration take precedence over environment variables 36 | ConfigContext config = new IntegrationTestConfigContext(usingEncryption); 37 | 38 | mantaClient = new MantaClient(config); 39 | testPathPrefix = IntegrationTestConfigContext.generateBasePath(config, this.getClass().getSimpleName()); 40 | mantaClient.putDirectory(testPathPrefix, true); 41 | } 42 | 43 | @AfterClass 44 | public void afterClass() throws IOException { 45 | IntegrationTestConfigContext.cleanupTestDirectory(mantaClient, testPathPrefix); 46 | } 47 | 48 | @Test(expectedExceptions = { ConfigurationException.class }) 49 | public final void testInvalidMantaUser() throws IOException { 50 | System.setProperty("manta.dumpConfig", "true"); 51 | final ConfigContext config = new ChainedConfigContext( 52 | new StandardConfigContext() 53 | .setMantaKeyId("some placeholder string") 54 | .setMantaUser("MY USERNAME"), 55 | new DefaultsConfigContext() 56 | 57 | ); 58 | 59 | try (final MantaClient client = new MantaClient(config)) { 60 | Assert.assertNotNull(client); 61 | 62 | final String name = UUID.randomUUID().toString(); 63 | final String path = config.getMantaUser() + "/stor/" + name; 64 | client.put(path, TEST_DATA); 65 | } 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/manta/client/TestSuiteSetup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.manta.client; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.testng.ITestContext; 13 | import org.testng.annotations.BeforeSuite; 14 | 15 | 16 | /** 17 | * Class containing one time test suite setup methods. 18 | * 19 | * @author Elijah Zupancic 20 | */ 21 | public class TestSuiteSetup { 22 | private Logger logger = LoggerFactory.getLogger(getClass()); 23 | 24 | @BeforeSuite 25 | public void setupSuite(final ITestContext context) { 26 | logger.info(context.getName()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/FailingInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.util.concurrent.atomic.AtomicLong; 13 | 14 | public class FailingInputStream extends InputStream { 15 | /** 16 | * End of file magic number. 17 | */ 18 | private static final int EOF = -1; 19 | 20 | /** 21 | * The wrapped InputStream 22 | */ 23 | private final InputStream wrapped; 24 | 25 | /** 26 | * Current read byte count. 27 | */ 28 | private final AtomicLong count = new AtomicLong(0L); 29 | 30 | /** 31 | * Minimum number of bytes to read before failing. 32 | */ 33 | private final long minimumBytes; 34 | 35 | /** 36 | * 37 | * @param wrapped InputStream to wrap 38 | * @param minimumBytes number of bytes to read successfully before failing 39 | */ 40 | public FailingInputStream(InputStream wrapped, int minimumBytes) { 41 | this.wrapped = wrapped; 42 | this.minimumBytes = minimumBytes; 43 | } 44 | 45 | @Override 46 | public int read(byte[] b) throws IOException { 47 | failAfterMinimum(b.length); 48 | int bytesRead = wrapped.read(b); 49 | count.addAndGet(bytesRead); 50 | return bytesRead; 51 | } 52 | 53 | @Override 54 | public int read(byte[] b, int off, int len) throws IOException { 55 | failAfterMinimum(len); 56 | int bytesRead = wrapped.read(b, off, len); 57 | count.addAndGet(bytesRead); 58 | return bytesRead; 59 | } 60 | 61 | @Override 62 | public int read() throws IOException { 63 | failAfterMinimum(1); 64 | // it's a byte, even though the return is int 65 | int nextByte = wrapped.read(); 66 | if (nextByte != EOF) { 67 | count.incrementAndGet(); 68 | } 69 | return nextByte; 70 | } 71 | 72 | private void failAfterMinimum(final int next) throws SpuriousIOException { 73 | if (count.get() + next > minimumBytes) { 74 | throw new SpuriousIOException("Read failure after byte " + minimumBytes); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/FailingInputStreamTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2019, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | 16 | @Test 17 | public class FailingInputStreamTest { 18 | 19 | public void testInputStreamFailsAfterExpectedOffset() throws IOException { 20 | RandomInputStream randomData = new RandomInputStream(100); 21 | InputStream fin = new FailingInputStream(randomData, 15); 22 | 23 | int bytesRead = fin.read(new byte[10]); 24 | Assert.assertEquals(10, bytesRead); 25 | 26 | Assert.assertThrows(() -> { 27 | fin.read(new byte[10]); 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/MantaAssert.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import com.joyent.manta.exception.MantaClientHttpResponseException; 11 | import com.joyent.manta.exception.MantaErrorCode; 12 | import com.joyent.manta.exception.MantaException; 13 | 14 | import java.io.IOException; 15 | 16 | /** 17 | * Assertions for verifying integration test behavior with Manta. 18 | * @author Elijah Zupancic 19 | */ 20 | public class MantaAssert { 21 | /** 22 | * Functional wrapper that validates if a given closures throws a 23 | * {@link MantaClientHttpResponseException} and that it has the 24 | * correct status code. 25 | * 26 | * @param expectedStatusCode HTTP status code to verify 27 | * @param expectedErrorCode error code as returned from Manta 28 | * @param function block to verify 29 | * @param return type 30 | * @return return value of underlying block 31 | */ 32 | public static R assertResponseFailureStatusCode( 33 | final int expectedStatusCode, final MantaErrorCode expectedErrorCode, 34 | final MantaFunction function) { 35 | boolean thrown = false; 36 | int actualStatusCode = -1; 37 | MantaErrorCode actualErrorCode = MantaErrorCode.UNDEFINED; 38 | R result = null; 39 | 40 | try { 41 | result = function.apply(); 42 | } catch (MantaClientHttpResponseException e) { 43 | actualStatusCode = e.getStatusCode(); 44 | actualErrorCode = e.getServerCode(); 45 | thrown = true; 46 | } catch (IOException e) { 47 | throw new MantaException(e); 48 | } 49 | 50 | if (!thrown) { 51 | String msg = String.format("Expected %s to be thrown, but it was not thrown", 52 | MantaClientHttpResponseException.class); 53 | throw new AssertionError(msg); 54 | } 55 | 56 | if (actualStatusCode != expectedStatusCode) { 57 | String msg = String.format("Expected HTTP status code [%d] was: %d", 58 | expectedStatusCode, actualStatusCode); 59 | throw new AssertionError(msg); 60 | } 61 | 62 | if (!actualErrorCode.equals(expectedErrorCode)) { 63 | String msg = String.format("Expected Manta error code [%s] was not received: %s", 64 | expectedErrorCode, actualErrorCode); 65 | throw new AssertionError(msg); 66 | } 67 | 68 | return result; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/MantaFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import com.joyent.manta.exception.MantaClientHttpResponseException; 11 | import com.joyent.manta.exception.MantaException; 12 | 13 | import java.io.IOException; 14 | 15 | /** 16 | * Function allowing us to make useful testing lamdas. 17 | * @author Elijah Zupancic 18 | */ 19 | @FunctionalInterface 20 | public interface MantaFunction { 21 | 22 | /** 23 | * A closure for wrapping sections of code for testing. 24 | * @return the function result 25 | */ 26 | R apply() throws MantaClientHttpResponseException, MantaException, IOException; 27 | } 28 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/MantaPathSuiteListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2019, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import com.joyent.manta.client.MantaClient; 11 | import com.joyent.manta.config.ConfigContext; 12 | import com.joyent.manta.config.IntegrationTestConfigContext; 13 | import org.apache.commons.lang3.BooleanUtils; 14 | import org.apache.commons.lang3.ObjectUtils; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | import org.testng.ISuite; 18 | import org.testng.ISuiteListener; 19 | 20 | import java.io.IOException; 21 | 22 | public class MantaPathSuiteListener implements ISuiteListener { 23 | 24 | private static final Logger LOG = LoggerFactory.getLogger(MantaPathSuiteListener.class); 25 | 26 | private ConfigContext config; 27 | 28 | @Override 29 | public void onStart(ISuite suite) { 30 | config = new IntegrationTestConfigContext(); 31 | LOG.info("Base manta path for suite {}: {}", suite.getName(), 32 | IntegrationTestConfigContext.generateSuiteBasePath(config)); 33 | } 34 | 35 | @Override 36 | public void onFinish(ISuite suite) { 37 | LOG.info("Expected test count: " + TestListingInterceptor.getObservedTestCount()); 38 | 39 | MantaClient mantaClient = new MantaClient(config); 40 | String path = IntegrationTestConfigContext.generateSuiteBasePath(config); 41 | 42 | if (ObjectUtils.firstNonNull( 43 | BooleanUtils.toBoolean(System.getProperty("it.dryRun")), 44 | false)) { 45 | LOG.warn("Skipping suite cleanup since dry-run is enabled."); 46 | return; 47 | } 48 | 49 | try { 50 | if (mantaClient.isDirectoryEmpty(path)) { 51 | LOG.info("Removing base suite path: {}", path); 52 | mantaClient.delete(path); 53 | } else { 54 | LOG.warn("Base suite directory {} is not empty; leaving in place", path); 55 | } 56 | } catch (IOException e) { 57 | LOG.warn("Unable to check on base suite path: {}", path, e); 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/RandomInputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import org.apache.commons.lang3.RandomUtils; 11 | 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.util.concurrent.atomic.AtomicLong; 15 | 16 | /** 17 | * {@link InputStream} implementation that generates random data. 18 | * 19 | * @author Elijah Zupancic 20 | */ 21 | public class RandomInputStream extends InputStream { 22 | /** 23 | * End of file magic number. 24 | */ 25 | private static final int EOF = -1; 26 | 27 | /** 28 | * Maximum number of bytes to generate. 29 | */ 30 | private final long maximumBytes; 31 | 32 | /** 33 | * Current generated byte count. 34 | */ 35 | private AtomicLong count = new AtomicLong(0L); 36 | 37 | /** 38 | * Creates a new instance. 39 | * @param maximumBytes maximum number of random bytes in stream 40 | */ 41 | public RandomInputStream(final long maximumBytes) { 42 | this.maximumBytes = maximumBytes; 43 | } 44 | 45 | @Override 46 | public int read() throws IOException { 47 | if (count.getAndIncrement() >= maximumBytes) { 48 | return EOF; 49 | } 50 | 51 | return RandomUtils.nextInt(0, Integer.MAX_VALUE); 52 | } 53 | 54 | @Override 55 | public int read(final byte[] b, final int off, final int len) throws IOException { 56 | if (count.get() >= maximumBytes) { 57 | return EOF; 58 | } 59 | 60 | final int bytesToRead; 61 | 62 | if (maximumBytes - count.get() >= len) { 63 | bytesToRead = len; 64 | } else { 65 | bytesToRead = (int)(maximumBytes - count.get()); 66 | } 67 | 68 | count.addAndGet(bytesToRead); 69 | 70 | final byte[] randomBytes = RandomUtils.nextBytes(bytesToRead); 71 | 72 | System.arraycopy(randomBytes, 0, b, off, bytesToRead); 73 | 74 | return bytesToRead; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/RandomInputStreamTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import org.testng.Assert; 11 | import org.testng.annotations.Test; 12 | 13 | import java.io.IOException; 14 | 15 | @Test 16 | public class RandomInputStreamTest { 17 | public void canDoSingleByteReadsForOnlyTheExpectedNumberOfBytes() throws IOException { 18 | final long expectedBytes = 1119; 19 | 20 | try (RandomInputStream stream = new RandomInputStream(expectedBytes)) { 21 | long actualBytesRead = 0; 22 | 23 | for (int readVal = stream.read(); readVal != -1; readVal = stream.read()) { 24 | actualBytesRead++; 25 | } 26 | 27 | Assert.assertEquals(actualBytesRead, expectedBytes, 28 | "Number bytes actually read didn't match actual bytes read"); 29 | } 30 | } 31 | 32 | public void canDoMultiByteReadsForOnlyTheExpectedNumberOfBytes() throws IOException { 33 | final long expectedBytes = 1119; 34 | 35 | try (RandomInputStream stream = new RandomInputStream(expectedBytes)) { 36 | long actualBytesRead = 0; 37 | int lastReadBytes; 38 | byte[] buffer = new byte[16]; 39 | 40 | while ((lastReadBytes = stream.read(buffer, 0, 16)) != -1) { 41 | actualBytesRead += lastReadBytes; 42 | } 43 | 44 | Assert.assertEquals(actualBytesRead, expectedBytes, 45 | "Number bytes actually read didn't match actual bytes read"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/SpuriousIOException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import java.io.IOException; 11 | 12 | public class SpuriousIOException extends IOException { 13 | 14 | private static final long serialVersionUID = 229727410007992086L; 15 | 16 | SpuriousIOException(String message) { 17 | super(message); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /java-manta-it/src/test/java/com/joyent/test/util/ThreeTriesRetryAnalyzer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. 3 | * 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | package com.joyent.test.util; 9 | 10 | import org.testng.ITestResult; 11 | import org.testng.Reporter; 12 | import org.testng.util.RetryAnalyzerCount; 13 | 14 | /** 15 | * Retries an integration test three times before it is considered a failure. 16 | * 17 | * @author Elijah Zupancic 18 | * @since 2.2.4 19 | */ 20 | public class ThreeTriesRetryAnalyzer extends RetryAnalyzerCount { 21 | private static final int TRIES = 3; 22 | 23 | public ThreeTriesRetryAnalyzer() { 24 | setCount(TRIES); 25 | } 26 | 27 | @Override 28 | public boolean retryMethod(final ITestResult result) { 29 | // If successful, don't retry 30 | if (result.isSuccess()) { 31 | return false; 32 | } 33 | 34 | // If unsuccessful, but we still have retries 35 | if (getCount() > 0) { 36 | result.setStatus(ITestResult.SUCCESS_PERCENTAGE_FAILURE); 37 | 38 | final String msg = String.format( 39 | "[%s]: Error in %s Retrying %d more times", 40 | Thread.currentThread().getName(), result.getName(), 41 | getCount()); 42 | Reporter.log(msg); 43 | 44 | return true; 45 | } 46 | 47 | // If unsuccessful and we are out of retries 48 | return false; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /java-manta-it/src/test/resources/Master-Yoda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/java-manta/9faa1e9d5c4265259addcb5d27d56ff1d07548ec/java-manta-it/src/test/resources/Master-Yoda.jpg -------------------------------------------------------------------------------- /java-manta-it/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | [%thread] %-5level %logger [%X{mantaLoadBalancerAddress} %X{mantaRequestId}] - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | --------------------------------------------------------------------------------