Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 32a0788dcc80a2154462090629bfb6acb672b34d 0 parents
@mtdowling mtdowling authored
Showing with 11,668 additions and 0 deletions.
  1. +24 −0 .gitignore
  2. +141 −0 LICENSE.md
  3. +265 −0 README.md
  4. +191 −0 build.xml
  5. +17 −0 build/phar-stub-min.php
  6. +33 −0 build/phar-stub.php
  7. +32 −0 composer.json
  8. +37 −0 phpunit.functional.xml.dist
  9. +46 −0 phpunit.xml.dist
  10. +90 −0 src/Aws/Common/Aws.php
  11. +146 −0 src/Aws/Common/Client/AbstractClient.php
  12. +70 −0 src/Aws/Common/Client/AbstractMissingFunctionOptionResolver.php
  13. +59 −0 src/Aws/Common/Client/AwsClientInterface.php
  14. +361 −0 src/Aws/Common/Client/ClientBuilder.php
  15. +95 −0 src/Aws/Common/Client/CredentialsOptionResolver.php
  16. +68 −0 src/Aws/Common/Client/ExponentialBackoffOptionResolver.php
  17. +37 −0 src/Aws/Common/Client/OptionResolverInterface.php
  18. +82 −0 src/Aws/Common/Client/SignatureOptionResolver.php
  19. +81 −0 src/Aws/Common/Command/JsonCommand.php
  20. +138 −0 src/Aws/Common/Credentials/AbstractCredentialsDecorator.php
  21. +64 −0 src/Aws/Common/Credentials/AbstractRefreshableCredentials.php
  22. +73 −0 src/Aws/Common/Credentials/CacheableCredentials.php
  23. +289 −0 src/Aws/Common/Credentials/Credentials.php
  24. +96 −0 src/Aws/Common/Credentials/CredentialsInterface.php
  25. +89 −0 src/Aws/Common/Credentials/RefreshableInstanceProfileCredentials.php
  26. +55 −0 src/Aws/Common/Enum.php
  27. +30 −0 src/Aws/Common/Exception/AwsExceptionInterface.php
  28. +22 −0 src/Aws/Common/Exception/BadMethodCallException.php
  29. +21 −0 src/Aws/Common/Exception/ClientExceptionInterface.php
  30. +22 −0 src/Aws/Common/Exception/DomainException.php
  31. +34 −0 src/Aws/Common/Exception/ExceptionFactoryInterface.php
  32. +59 −0 src/Aws/Common/Exception/ExceptionListener.php
  33. +50 −0 src/Aws/Common/Exception/InstanceProfileCredentialsException.php
  34. +22 −0 src/Aws/Common/Exception/InvalidArgumentException.php
  35. +100 −0 src/Aws/Common/Exception/NamespaceExceptionFactory.php
  36. +49 −0 src/Aws/Common/Exception/Parser/DefaultJsonExceptionParser.php
  37. +56 −0 src/Aws/Common/Exception/Parser/DefaultXmlExceptionParser.php
  38. +40 −0 src/Aws/Common/Exception/Parser/ExceptionParserInterface.php
  39. +22 −0 src/Aws/Common/Exception/RuntimeException.php
  40. +21 −0 src/Aws/Common/Exception/ServerExceptionInterface.php
  41. +150 −0 src/Aws/Common/Exception/ServiceResponseException.php
  42. +85 −0 src/Aws/Common/HostNameUtils.php
  43. +62 −0 src/Aws/Common/InstanceMetadata/InstanceMetadataClient.php
  44. +45 −0 src/Aws/Common/InstanceMetadata/Waiter/ServiceAvailable.php
  45. +62 −0 src/Aws/Common/Signature/AbstractEndpointSignature.php
  46. +121 −0 src/Aws/Common/Signature/AbstractSignature.php
  47. +42 −0 src/Aws/Common/Signature/EndpointSignatureInterface.php
  48. +37 −0 src/Aws/Common/Signature/SignatureInterface.php
  49. +69 −0 src/Aws/Common/Signature/SignatureListener.php
  50. +32 −0 src/Aws/Common/Signature/SignatureV2.php
  51. +98 −0 src/Aws/Common/Signature/SignatureV3.php
  52. +205 −0 src/Aws/Common/Signature/SignatureV4.php
  53. +30 −0 src/Aws/Common/ToArrayInterface.php
  54. +85 −0 src/Aws/Common/Waiter/AbstractResourceWaiter.php
  55. +128 −0 src/Aws/Common/Waiter/AbstractWaiter.php
  56. +62 −0 src/Aws/Common/Waiter/CallableWaiter.php
  57. +43 −0 src/Aws/Common/Waiter/ResourceWaiterInterface.php
  58. +64 −0 src/Aws/Common/Waiter/WaiterClassFactory.php
  59. +32 −0 src/Aws/Common/Waiter/WaiterFactoryInterface.php
  60. +63 −0 src/Aws/Common/Waiter/WaiterInterface.php
  61. +18 −0 src/Aws/Common/aws-config.json
  62. +153 −0 src/Aws/DynamoDb/DynamoDbClient.php
  63. +29 −0 src/Aws/DynamoDb/Enum/Actions.php
  64. +39 −0 src/Aws/DynamoDb/Enum/Conditions.php
  65. +31 −0 src/Aws/DynamoDb/Enum/ReturnValues.php
  66. +30 −0 src/Aws/DynamoDb/Enum/TableStatus.php
  67. +30 −0 src/Aws/DynamoDb/Enum/Types.php
  68. +24 −0 src/Aws/DynamoDb/Exception/AccessDeniedException.php
  69. +24 −0 src/Aws/DynamoDb/Exception/ConditionalCheckFailedException.php
  70. +24 −0 src/Aws/DynamoDb/Exception/DynamoDbException.php
  71. +24 −0 src/Aws/DynamoDb/Exception/IncompleteSignatureException.php
  72. +24 −0 src/Aws/DynamoDb/Exception/InternalFailure.php
  73. +24 −0 src/Aws/DynamoDb/Exception/InternalServerErrorException.php
  74. +24 −0 src/Aws/DynamoDb/Exception/LimitExceededException.php
  75. +24 −0 src/Aws/DynamoDb/Exception/MissingAuthenticationTokenException.php
  76. +24 −0 src/Aws/DynamoDb/Exception/ProvisionedThroughputExceededException.php
  77. +24 −0 src/Aws/DynamoDb/Exception/ResourceInUseException.php
  78. +24 −0 src/Aws/DynamoDb/Exception/ResourceNotFoundException.php
  79. +24 −0 src/Aws/DynamoDb/Exception/ServiceUnavailableException.php
  80. +24 −0 src/Aws/DynamoDb/Exception/ThrottlingException.php
  81. +55 −0 src/Aws/DynamoDb/Exception/UnprocessedWriteRequestsException.php
  82. +24 −0 src/Aws/DynamoDb/Exception/UnrecognizedClientException.php
  83. +24 −0 src/Aws/DynamoDb/Exception/ValidationException.php
  84. +189 −0 src/Aws/DynamoDb/Model/Attribute.php
  85. +66 −0 src/Aws/DynamoDb/Model/BatchGetItemIterator.php
  86. +36 −0 src/Aws/DynamoDb/Model/BatchRequest/AbstractWriteRequest.php
  87. +62 −0 src/Aws/DynamoDb/Model/BatchRequest/DeleteRequest.php
  88. +68 −0 src/Aws/DynamoDb/Model/BatchRequest/PutRequest.php
  89. +48 −0 src/Aws/DynamoDb/Model/BatchRequest/UnprocessedRequest.php
  90. +224 −0 src/Aws/DynamoDb/Model/BatchRequest/WriteRequestBatch.php
  91. +86 −0 src/Aws/DynamoDb/Model/BatchRequest/WriteRequestBatchTransfer.php
  92. +32 −0 src/Aws/DynamoDb/Model/BatchRequest/WriteRequestInterface.php
  93. +269 −0 src/Aws/DynamoDb/Model/Item.php
  94. +122 −0 src/Aws/DynamoDb/Model/Key.php
  95. +42 −0 src/Aws/DynamoDb/Model/ListTablesIterator.php
  96. +41 −0 src/Aws/DynamoDb/Model/QueryIterator.php
  97. +75 −0 src/Aws/DynamoDb/Model/ScanIterator.php
  98. +74 −0 src/Aws/DynamoDb/Plugin/ItemMarshallerPlugin.php
  99. +292 −0 src/Aws/DynamoDb/Resources/client.json
  100. +58 −0 src/Aws/DynamoDb/ThrottlingErrorChecker.php
  101. +52 −0 src/Aws/DynamoDb/Waiter/TableExists.php
  102. +48 −0 src/Aws/DynamoDb/Waiter/TableNotExists.php
  103. +24 −0 src/Aws/Sts/Exception/IncompleteSignatureException.php
  104. +24 −0 src/Aws/Sts/Exception/InternalFailureException.php
  105. +24 −0 src/Aws/Sts/Exception/InvalidActionException.php
  106. +24 −0 src/Aws/Sts/Exception/InvalidClientTokenIdException.php
  107. +24 −0 src/Aws/Sts/Exception/InvalidParameterCombinationException.php
  108. +24 −0 src/Aws/Sts/Exception/InvalidParameterValueException.php
  109. +24 −0 src/Aws/Sts/Exception/InvalidQueryParameterException.php
  110. +24 −0 src/Aws/Sts/Exception/MalformedQueryStringException.php
  111. +24 −0 src/Aws/Sts/Exception/MissingActionException.php
  112. +24 −0 src/Aws/Sts/Exception/MissingAuthenticationTokenException.php
  113. +24 −0 src/Aws/Sts/Exception/MissingParameterException.php
  114. +24 −0 src/Aws/Sts/Exception/OptInRequiredException.php
  115. +25 −0 src/Aws/Sts/Exception/RequestExpiredException.php
  116. +24 −0 src/Aws/Sts/Exception/ServiceUnavailableException.php
  117. +24 −0 src/Aws/Sts/Exception/StsException.php
  118. +24 −0 src/Aws/Sts/Exception/ThrottlingException.php
  119. +69 −0 src/Aws/Sts/Resources/client.json
  120. +92 −0 src/Aws/Sts/StsClient.php
  121. +12 −0 test_services.json.dist
  122. +34 −0 tests/Aws/Tests/Common/AwsTest.php
  123. +146 −0 tests/Aws/Tests/Common/Client/AbstractClientTest.php
  124. +34 −0 tests/Aws/Tests/Common/Client/AbstractMissingFunctionOptionResolverTest.php
  125. +96 −0 tests/Aws/Tests/Common/Client/ClientBuilderTest.php
  126. +68 −0 tests/Aws/Tests/Common/Client/CredentialsOptionResolverTest.php
  127. +42 −0 tests/Aws/Tests/Common/Client/ExponentialBackoffOptionResolverTest.php
  128. +50 −0 tests/Aws/Tests/Common/Client/SignatureOptionResolverTest.php
  129. +89 −0 tests/Aws/Tests/Common/Command/JsonCommandTest.php
  130. +39 −0 tests/Aws/Tests/Common/Credentials/AbstractCredentialsDecoratorTest.php
  131. +28 −0 tests/Aws/Tests/Common/Credentials/AbstractRefreshableCredentialsTest.php
  132. +83 −0 tests/Aws/Tests/Common/Credentials/CacheableCredentialsTest.php
  133. +204 −0 tests/Aws/Tests/Common/Credentials/CredentialsTest.php
  134. +126 −0 tests/Aws/Tests/Common/Credentials/RefreshableInstanceProfileCredentialsIntegrationTest.php
  135. +70 −0 tests/Aws/Tests/Common/Credentials/RefreshableInstanceProfileCredentialsTest.php
  136. +55 −0 tests/Aws/Tests/Common/EnumTest.php
  137. +47 −0 tests/Aws/Tests/Common/Exception/ExceptionListenerTest.php
  138. +20 −0 tests/Aws/Tests/Common/Exception/InstanceProfileCredentialsExceptionTest.php
  139. +37 −0 tests/Aws/Tests/Common/Exception/NamespaceExceptionFactoryTest.php
  140. +54 −0 tests/Aws/Tests/Common/Exception/Parser/DefaultJsonExceptionParserTest.php
  141. +62 −0 tests/Aws/Tests/Common/Exception/Parser/DefaultXmlExceptionParserTest.php
  142. +29 −0 tests/Aws/Tests/Common/Exception/ServiceResponseExceptionTest.php
  143. +64 −0 tests/Aws/Tests/Common/HostNameUtilsTest.php
  144. +29 −0 tests/Aws/Tests/Common/InstanceMetadata/InstanceMetadataClientTest.php
  145. +96 −0 tests/Aws/Tests/Common/Signature/AbstractSignatureTest.php
  146. +43 −0 tests/Aws/Tests/Common/Signature/SignatureListenerTest.php
  147. +25 −0 tests/Aws/Tests/Common/Signature/SignatureV2Test.php
  148. +133 −0 tests/Aws/Tests/Common/Signature/SignatureV3Test.php
  149. +170 −0 tests/Aws/Tests/Common/Signature/SignatureV4Test.php
  150. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-key-duplicate.authz
  151. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-key-duplicate.creq
  152. +7 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-key-duplicate.req
  153. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-key-duplicate.sreq
  154. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-key-duplicate.sts
  155. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-order.authz
  156. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-order.creq
  157. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-order.req
  158. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-order.sreq
  159. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-order.sts
  160. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-trim.authz
  161. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-trim.creq
  162. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-trim.req
  163. +6 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-trim.sreq
  164. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-header-value-trim.sts
  165. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative-relative.authz
  166. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative-relative.creq
  167. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative-relative.req
  168. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative-relative.sreq
  169. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative-relative.sts
  170. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative.authz
  171. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative.creq
  172. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative.req
  173. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative.sreq
  174. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-relative.sts
  175. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-dot-slash.authz
  176. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-dot-slash.creq
  177. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-dot-slash.req
  178. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-dot-slash.sreq
  179. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-dot-slash.sts
  180. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-pointless-dot.authz
  181. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-pointless-dot.creq
  182. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-pointless-dot.req
  183. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-pointless-dot.sreq
  184. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash-pointless-dot.sts
  185. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash.authz
  186. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash.creq
  187. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash.req
  188. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash.sreq
  189. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slash.sts
  190. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slashes.authz
  191. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slashes.creq
  192. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slashes.req
  193. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slashes.sreq
  194. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-slashes.sts
  195. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-space.authz
  196. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-space.creq
  197. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-space.req
  198. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-space.sreq
  199. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-space.sts
  200. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-unreserved.authz
  201. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-unreserved.creq
  202. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-unreserved.req
  203. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-unreserved.sreq
  204. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-unreserved.sts
  205. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-utf8.authz
  206. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-utf8.creq
  207. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-utf8.req
  208. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-utf8.sreq
  209. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-utf8.sts
  210. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-empty-query-key.authz
  211. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-empty-query-key.creq
  212. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-empty-query-key.req
  213. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-empty-query-key.sreq
  214. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-empty-query-key.sts
  215. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key-case.authz
  216. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key-case.creq
  217. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key-case.req
  218. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key-case.sreq
  219. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key-case.sts
  220. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key.authz
  221. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key.creq
  222. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key.req
  223. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key.sreq
  224. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-key.sts
  225. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-value.authz
  226. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-value.creq
  227. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-value.req
  228. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-value.sreq
  229. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-order-value.sts
  230. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-unreserved.authz
  231. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-unreserved.creq
  232. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-unreserved.req
  233. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-unreserved.sreq
  234. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query-unreserved.sts
  235. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query.authz
  236. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query.creq
  237. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query.req
  238. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query.sreq
  239. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-query.sts
  240. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-ut8-query.authz
  241. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-ut8-query.creq
  242. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-ut8-query.req
  243. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-ut8-query.sreq
  244. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla-ut8-query.sts
  245. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla.authz
  246. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla.creq
  247. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla.req
  248. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla.sreq
  249. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/get-vanilla.sts
  250. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-case.authz
  251. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-case.creq
  252. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-case.req
  253. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-case.sreq
  254. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-case.sts
  255. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-sort.authz
  256. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-sort.creq
  257. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-sort.req
  258. +6 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-sort.sreq
  259. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-key-sort.sts
  260. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-value-case.authz
  261. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-value-case.creq
  262. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-value-case.req
  263. +6 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-value-case.sreq
  264. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-header-value-case.sts
  265. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-empty-query-value.authz
  266. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-empty-query-value.creq
  267. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-empty-query-value.req
  268. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-empty-query-value.sreq
  269. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-empty-query-value.sts
  270. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-query.authz
  271. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-query.creq
  272. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-query.req
  273. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-query.sreq
  274. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla-query.sts
  275. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla.authz
  276. +8 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla.creq
  277. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla.req
  278. +5 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla.sreq
  279. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-vanilla.sts
  280. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded-parameters.authz
  281. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded-parameters.creq
  282. +6 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded-parameters.req
  283. +7 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded-parameters.sreq
  284. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded-parameters.sts
  285. +1 −0  tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded.authz
  286. +9 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded.creq
  287. +6 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded.req
  288. +7 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded.sreq
  289. +4 −0 tests/Aws/Tests/Common/Signature/aws4_testsuite/post-x-www-form-urlencoded.sts
  290. +57 −0 tests/Aws/Tests/Common/Waiter/AbstractResourceWaiterTest.php
  291. +111 −0 tests/Aws/Tests/Common/Waiter/AbstractWaiterTest.php
  292. +42 −0 tests/Aws/Tests/Common/Waiter/CallableWaiterTest.php
  293. +27 −0 tests/Aws/Tests/Common/Waiter/WaiterClassFactoryTest.php
  294. +118 −0 tests/Aws/Tests/DynamoDb/DynamoDbClientTest.php
  295. +30 −0 tests/Aws/Tests/DynamoDb/Exception/UnprocessedWriteRequestsExceptionTest.php
  296. +454 −0 tests/Aws/Tests/DynamoDb/Integration/IntegrationTest.php
  297. +158 −0 tests/Aws/Tests/DynamoDb/Model/AttributeTest.php
  298. +61 −0 tests/Aws/Tests/DynamoDb/Model/BatchGetItemIteratorTest.php
  299. +21 −0 tests/Aws/Tests/DynamoDb/Model/BatchRequest/AbstractWriteRequestTest.php
  300. +36 −0 tests/Aws/Tests/DynamoDb/Model/BatchRequest/DeleteRequestTest.php
Sorry, we could not display the entire diff because too many files (336) changed.
24 .gitignore
@@ -0,0 +1,24 @@
+# Exclude build artifacts
+*.phar
+build/artifacts
+
+# Exclude common cruft
+.idea
+.DS_Store
+.swp
+.build
+
+# Don't ship our composer.lock file
+composer.lock
+
+# Don't commit vendor folders
+vendor
+
+# Don't commit sensitive information
+phpunit.xml
+phpunit.functional.xml
+test_services.json
+
+# Exclude proprietary build info
+Config
+Makefile
141 LICENSE.md
@@ -0,0 +1,141 @@
+# Apache License
+Version 2.0, January 2004
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+## 1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1
+through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the
+License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled
+by, or are under common control with that entity. For the purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract
+or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial
+ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software
+source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form,
+including but not limited to compiled object code, generated documentation, and conversions to other media
+types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License,
+as indicated by a copyright notice that is included in or attached to the work (an example is provided in the
+Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from)
+the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent,
+as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not
+include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work
+and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any
+modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to
+Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to
+submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of
+electronic, verbal, or written communication sent to the Licensor or its representatives, including but not
+limited to communication on electronic mailing lists, source code control systems, and issue tracking systems
+that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but
+excluding communication that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been
+received by Licensor and subsequently incorporated within the Work.
+
+## 2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
+Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+## 3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent
+license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such
+license applies only to those patent claims licensable by such Contributor that are necessarily infringed by
+their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such
+Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim
+or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work
+constitutes direct or contributory patent infringement, then any patent licenses granted to You under this
+License for that Work shall terminate as of the date such litigation is filed.
+
+## 4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without
+modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ 2. You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent,
+ trademark, and attribution notices from the Source form of the Work, excluding those notices that do
+ not pertain to any part of the Derivative Works; and
+
+ 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that
+ You distribute must include a readable copy of the attribution notices contained within such NOTICE
+ file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed as part of the Derivative Works; within
+ the Source form or documentation, if provided along with the Derivative Works; or, within a display
+ generated by the Derivative Works, if and wherever such third-party notices normally appear. The
+ contents of the NOTICE file are for informational purposes only and do not modify the License. You may
+ add Your own attribution notices within Derivative Works that You distribute, alongside or as an
+ addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be
+ construed as modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide additional or different license
+terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative
+Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the
+conditions stated in this License.
+
+## 5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by
+You to the Licensor shall be under the terms and conditions of this License, without any additional terms or
+conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate
+license agreement you may have executed with Licensor regarding such Contributions.
+
+## 6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks, service marks, or product names of
+the Licensor, except as required for reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+## 7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor
+provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+## 8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless
+required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any
+Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential
+damages of any character arising as a result of this License or out of the use or inability to use the Work
+(including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has been advised of the possibility
+of such damages.
+
+## 9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for,
+acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this
+License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole
+responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold
+each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason
+of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
265 README.md
@@ -0,0 +1,265 @@
+# AWS SDK for PHP
+
+The AWS SDK for PHP enables PHP developers to build solutions with Amazon Simple Storage Service (Amazon S3), Amazon DynamoDB, Amazon Elastic Compute Cloud (Amazon EC2), Amazon DynamoDB, and more. With the AWS SDK for PHP, developers can get started in minutes with a single, downloadable phar, or by using [Composer](http://getcomposer.org).
+
+## Version 2
+
+A recent version 2 rewrite of the AWS SDK for PHP provides developers with a more extendable, easy to use, and performant client. The new version of the SDK utilizes [Guzzle](http://guzzlephp.org), a PHP HTTP client framework that provides various performance boosts such as persistent connection management and an extendable plugin system.
+
+## Features
+
+* Rewritten using PHP 5.3 and namespaces to be PSR-0, PSR-1, and PSR-2 compliant
+* Persistent connection management for both serial and parallel requests
+* [Symfony2 EventDispatcher](http://symfony.com/doc/master/components/event_dispatcher/introduction.html) hooks that allow for extremely customizable client behavior
+* All request and response entity bodies are stored in php://temp streams that help protect you from running out of memory
+* Transient networking failures are automatically retried using truncated exponential backoff
+* You can utilize the various [plugins provided by Guzzle](http://guzzlephp.org/tour/http.html#plugins-for-common-http-request-behavior), including caching and over the wire logging
+* Includes a "waiter" system that allows you to poll a resource until it is in a predefined state (e.g. wait for an Amazon DynamoDB table to become active)
+* Includes iterators so that you can easily iterate over paginated responses without having to manually send subsequent requests
+* Service specific exceptions are thrown when an error occurs
+
+## Minimum Requirements
+
+* You have a valid AWS account, and you've already signed up for the services you want to use
+* PHP 5.3.2+ compiled with the cURL extension
+* A recent version of cURL 7.16.2+ compiled with OpenSSL and zlib
+
+## Getting Started
+
+### Signing up for Amazon Web Services
+
+Before you can begin, you must sign up for each service you want to use.
+
+To sign up for a service:
+
+* Go to the home page for the service. You can find a list of services on
+ [aws.amazon.com/products](http://aws.amazon.com/products).
+* Click the Sign Up button on the top right corner of the page. If you don't already have an AWS account, you
+ are prompted to create one as part of the sign up process.
+* Follow the on-screen instructions.
+* AWS sends you a confirmation e-mail after the sign-up process is complete. At any time, you can view your
+ current account activity and manage your account by going to [aws.amazon.com](http://aws.amazon.com) and
+ clicking "Your Account".
+
+### Installing
+
+#### Installing via Composer
+
+The recommended way to install the AWS SDK for PHP is through [Composer](http://getcomposer.org).
+
+1. Add ``"amazonwebservices/aws-sdk-for-php"`` as a dependency in your project's ``composer.json`` file:
+
+ {
+ "require": {
+ "amazonwebservices/aws-sdk-for-php": "*"
+ }
+ }
+
+ Consider tightening your dependencies to a known version when deploying mission critical applications (e.g. ``2.0.*``).
+
+2. Download and install Composer:
+
+ curl -s http://getcomposer.org/installer | php
+
+3. Install your dependencies:
+
+ php composer.phar install
+
+4. Require Composer's autoloader
+
+ Composer also prepares an autoload file that's capable of autoloading all of the classes in any of the libraries that it downloads. To use it, just add the following line to your code's bootstrap process:
+
+ require 'vendor/autoload.php';
+
+You can find out more on how to install Composer, configure autoloading, and other best-practices for defining dependencies at [getcomposer.org](http://getcomposer.org).
+
+#### Installing via phar
+
+Each release of the AWS SDK for PHP ships with a pre-packaged phar file containing all of the classes you will need to run the SDK. Including the phar in your scripts automatically registers a class autoloader for the AWS SDK for PHP and all of its dependencies. Bundled with the phar file are other required libraries or libraries that you might find useful:
+
+ - [Guzzle](https://github.com/guzzle/guzzle) for HTTP requests
+ - [Symfony2 EventDispatcher](http://symfony.com/doc/master/components/event_dispatcher/introduction.html) for events
+ - [Monolog](https://github.com/seldaek/monolog) for logging
+ - [Doctrine\Common](https://github.com/doctrine/common) for caching
+
+## Using the SDK
+
+### Quick Start
+
+You can quickly get up and running by using a web service client's factory method to instantiate clients as needed.
+
+ <?php
+
+ // Include the SDK using the phar
+ require 'aws.phar';
+
+ use Aws\DynamoDb\DynamoDbClient;
+
+ // Instantiate the DynamoDB client with your AWS credentials
+ $client = DynamoDbClient::factory(array(
+ 'access_key_id' => 'your-aws-access-key-id',
+ 'secret_access_key' => 'your-aws-secret-access-key'
+ ));
+
+ $table = 'posts';
+
+ // Create a "posts" table
+ $client->createTable(array(
+ 'TableName' => $table,
+ 'KeySchema' => array(
+ 'HashKeyElement' => array(
+ 'AttributeName' => 'slug',
+ 'AttributeType' => 'S'
+ )
+ ),
+ 'ProvisionedThroughput' => array(
+ 'ReadCapacityUnits' => 10,
+ 'WriteCapacityUnits' => 5
+ )
+ ));
+
+ // Wait until the table is created and active
+ $client->waitUntil('TableExists', $table);
+
+ echo "The {$table} table has been created.\n";
+
+Note: Instantiating a client without providing credentials will cause the client to attempt to retrieve [IAM Instance Profile credentials](http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/UsingIAM.html#UsingIAMrolesWithAmazonEC2Instances).
+
+The syntax above (**"shorthand"** syntax) for creating a table should look familiar to those who have used the SDK prior to version 2.0. One difference is that *every* service operation (or "command") now accepts only a single array as an argument.
+
+Borrowed from the Guzzle framework, the SDK now supports a new **"command"** syntax for defining commands. The command approach is a more object-oriented and chainable approach to building requests to AWS services, and it can be especially useful when you want to manipulate the command object before execution or need to execute several commands in parallel.
+
+The following shows how to perform a DynamoDB `ListTables` command using both syntax forms:
+
+ // "shorthand" syntax
+ $result = $client->listTables(array('Limit' => 5));
+
+ // "command" syntax
+ $command = $client->getCommand('ListTables');
+ $command->set('Limit', 5);
+ $result = $command->execute();
+
+### Using the Service Builder
+
+When using the SDK, you have the option to use individual factory methods for each client or the `Aws\Common\Aws` class to build your clients. The ``Aws\Common\Aws`` class is a service builder and dependency injection container for the SDK and is the recommended way for instantiating clients. This class allows you to share configuration options between multiple services and pre-wires short service names with the appropriate client class.
+
+Below is an example showing how to use the service builder to retrieve a ``Aws\DynamoDb\DynamoDbClient`` and how to perform the `GetItem` operation using the command syntax.
+
+Note: Unlike the prior SDK, service clients throw exceptions for failed requests. Be sure to use `try` and `catch` blocks appropriately.
+
+ <?php
+
+ // Include the SDK using the phar
+ require 'aws.phar';
+
+ use Aws\Common\Aws;
+ use Aws\DynamoDb\Exception\DynamoDbException;
+
+ // Create a service building using shared credentials for each service
+ $aws = Aws::factory(array(
+ 'access_key_id' => 'your-aws-access-key-id',
+ 'secret_access_key' => 'your-aws-secret-access-key'
+ ));
+
+ // Retrieve the DynamoDB client by its short name from the service builder
+ $client = $aws->get('dynamo_db');
+
+ // Get an item from the "posts" table using the command syntax
+ try {
+ $result = $client->getCommand('GetItem')
+ ->set('TableName', 'posts')
+ ->set('Key', $client->formatAttributes(array(
+ 'HashKeyElement' => 'using-dynamodb-with-the-php-sdk'
+ ))
+ ->set('ConsistentRead', true)
+ ->execute();
+
+ print_r($result);
+ } catch (DynamoDbException $e) {
+ echo 'The item could not be retrieved.';
+ }
+
+Passing an associative array of parameters to the first or second argument of ``Aws\Common\Aws::factory()`` will treat the parameters as shared parameters across all clients generated by the builder. In the above example, we are telling the service builder to use the same credentials for every client.
+
+### Configuration
+
+When passing an array of parameters to the first argument of ``Aws\Common\Aws::factory()``, the service builder will load the default ``aws-config.json`` file and merge the array of shared parameters into the default configuration.
+
+Excerpt from src/Aws/Common/aws-config.json:
+
+ {
+ "services": {
+ "default_settings": {
+ "params": {}
+ },
+ "dynamo_db": {
+ "extends": "default_settings",
+ "class": "Aws\\DynamoDb\\DynamoDbClient"
+ },
+ "sts": {
+ "extends": "default_settings",
+ "class": "Aws\\Sts\\StsClient"
+ }
+ }
+ }
+
+The aws-config.json file provides default configuration settings for associating client classes with service names. This file tells the ``Aws\Common\Aws`` service builder which class the instantiate when you reference a client by name.
+
+None of the service configurations have defined ``access_key_id`` or ``secret_access_key`` settings. Unless you wish to use IAM Instance Profile credentials, you will need to supply credentials to the service builder in order to use access credentials with each client. For example, the code sample in _Using the Service Builder_ is using the default aws-config.json file and merging shared credentials into each client by passing an array into the first argument of ``Aws\Common\Aws::factory()``.
+
+### Using a custom configuration file
+
+You can use a custom configuration file that allows you to create custom named clients with pre-configured settings.
+
+Let's say you want to use the default ``aws-config.json`` settings, but you want to supply your keys using a configuration file. Each service defined in the default configuration file extends from ``default_settings`` service. You can create a custom configuration file that extends the default configuration file and add credentials to the ``default_settings`` service:
+
+ {
+ "extends": ["/path/to/src/Aws/Common/aws-config.json"],
+ "services": {
+ "default_settings": {
+ "params": {
+ "access_key_id": "your-aws-access-key-id",
+ "secret_access_key": "your-aws-secret-access-key"
+ }
+ }
+ }
+ }
+
+You can use your custom configuration file with ``Aws\Common\Aws`` by passing the full path to the configuration file in the first argument of the ``factory()`` method:
+
+ <?php
+
+ require 'aws.phar';
+
+ use Aws\Common\Aws;
+
+ $aws = Aws::factory('/path/to/custom_config.json');
+
+You can create custom named services if you need to use multiple accounts with the same service:
+
+ {
+ "extends": ["/path/to/src/Aws/Common/aws-config.json"],
+ "services": {
+ "lorem.dynamo_db": {
+ "extends": "dynamo_db",
+ "params": {
+ "access_key_id": "foo",
+ "secret_access_key": "baz"
+ }
+ },
+ "ipsum.dynamo_db": {
+ "extends": "dynamo_db",
+ "params": {
+ "access_key_id": "abc",
+ "secret_access_key": "123"
+ }
+ }
+ }
+ }
+
+## Additional Information
+
+* AWS SDK for PHP: <http://aws.amazon.com/sdkforphp>
+* Documentation: <http://docs.amazonwebservices.com/AWSSDKforPHP/latest/>
+* License: <http://aws.amazon.com/apache2.0/>
+* Forums: <http://aws.amazon.com/forums>
191 build.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="aws-sdk-for-php" default="package">
+
+ <property name="dir.output" value="${project.basedir}/build/artifacts" />
+ <property name="coverage" value="false" />
+ <property name="mock" value="false" />
+ <property name="min" value="false" />
+ <property name="sdk_url" value="http://aws.amazon.com/sdkforphp/" />
+
+ <fileset id="src_files" dir="${project.basedir}/src" includes="**/*.php" />
+
+ <target name="test" description="Run unit tests" depends="test-init">
+ <exec passthru="true" command="phpunit" />
+ </target>
+
+ <target name="integration" description="Run integration tests">
+ <if>
+ <available file="phpunit.functional.xml" />
+ <then>
+ <if>
+ <equals arg1="${mock}" arg2="true" />
+ <then>
+ <echo>php -d mock=true `which phpunit` -c phpunit.functional.xml</echo>
+ <exec passthru="true" command="php -d mock=true `which phpunit` -c phpunit.functional.xml" />
+ </then>
+ <else>
+ <exec passthru="true" command="phpunit -c phpunit.functional.xml" />
+ </else>
+ </if>
+ </then>
+ <else>
+ <fail>You must copy phpunit.functional.dist to phpunit.functional.xml and modify the appropriate property settings</fail>
+ </else>
+ </if>
+ </target>
+
+ <target name="package" description="Create a phar with an autoloader">
+ <phingcall target="test-init" />
+ <pharpackage destfile="build/aws.phar" stub="build/phar-stub.php" signature="md5" basedir=".">
+ <fileset dir=".">
+ <!-- Add AWS classes -->
+ <include name="src/**/*.php" />
+ <include name="src/**/*.json" />
+ <!-- Include the Symfony2 class loader component -->
+ <include name="vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php" />
+ <!-- Install Guzzle and its dependencies -->
+ <include name="vendor/guzzle/guzzle/src/**/*.php" />
+ <include name="vendor/symfony/event-dispatcher/**/*.php" />
+ <include name="vendor/doctrine/common/lib/Doctrine/Common/Cache/*.php" />
+ <include name="vendor/monolog/monolog/src/**/*.php" />
+ </fileset>
+ <metadata>
+ <element name="link" value="${sdk_url}" />
+ </metadata>
+ </pharpackage>
+ <exec command="php -d aws_phar=aws.phar `which phpunit`" passthru="true" />
+ </target>
+
+ <target name="package-min" description="Builds a minimal phar package">
+ <phingcall target="test-init" />
+ <pharpackage destfile="build/aws.min.phar" stub="build/phar-stub-min.php" signature="md5" basedir=".">
+ <fileset dir=".">
+ <include name="src/**/*.php" />
+ <include name="src/**/*.json" />
+ </fileset>
+ <metadata>
+ <element name="link" value="${sdk_url}" />
+ </metadata>
+ </pharpackage>
+ <exec command="php -d aws_phar=aws.min.phar `which phpunit`" passthru="true" />
+ </target>
+
+ <target name="test-init" description="Initialize test dependencies">
+ <if>
+ <available file="composer.phar" />
+ <then>
+ <echo>Composer is installed</echo>
+ </then>
+ <else>
+ <echo message="Installing composer" />
+ <exec command="curl -s http://getcomposer.org/installer | php" passthru="true" />
+ <exec command="php composer.phar install --dev" passthru="true" />
+ </else>
+ </if>
+ <copy file="phpunit.xml.dist" tofile="phpunit.xml" overwrite="false" />
+ <copy file="phpunit.functional.xml.dist" tofile="phpunit.functional.xml" overwrite="false" />
+ <copy file="test_services.json.dist" tofile="test_services.json" overwrite="false" />
+ </target>
+
+ <target name="clean">
+ <delete dir="${dir.output}"/>
+ </target>
+
+ <target name="prepare" depends="clean,test-init">
+ <mkdir dir="${dir.output}"/>
+ <mkdir dir="${dir.output}/logs" />
+ </target>
+
+ <target name="clean-dependencies">
+ <delete dir="${project.basedir}/vendor"/>
+ <delete file="composer.lock" />
+ </target>
+
+ <target name="update-dependencies">
+ <exec command="php composer.phar update --dev" passthru="true" />
+ </target>
+
+ <target name="coverage">
+ <mkdir dir="${dir.output}/logs" />
+ <exec passthru="true" command="phpunit --coverage-html=${dir.output}/coverage --coverage-clover=${dir.output}/logs/clover.xml" />
+ </target>
+
+ <target name="phpdepend">
+ <delete dir="${dir.output}/pdepend" includeemptydirs="true" verbose="true" failonerror="true" />
+ <mkdir dir="${dir.output}/pdepend" />
+ <phpdepend>
+ <fileset refid="src_files" />
+ <analyzer type="coderank-mode" value="method"/>
+ <logger type="jdepend-chart" outfile="${dir.output}/pdepend/jdepend-chart.svg" />
+ <logger type="overview-pyramid" outfile="${dir.output}/pdepend/overview-pyramid.svg" />
+ <logger type="jdepend-chart" outfile="${dir.output}/pdepend/jdepend-chart.png" />
+ <logger type="overview-pyramid" outfile="${dir.output}/pdepend/overview-pyramid.png" />
+ <logger type="jdepend-xml" outfile="${dir.output}/pdepend/jdepend.xml" />
+ <logger type="phpunit-xml" outfile="${dir.output}/pdepend/phpunit.xml" />
+ <logger type="summary-xml" outfile="${dir.output}/pdepend/summary.xml" />
+ </phpdepend>
+ </target>
+
+ <target name="phpcs">
+ <delete dir="${dir.output}/phpcs" includeemptydirs="true" verbose="true" failonerror="true" />
+ <mkdir dir="${dir.output}/phpcs" />
+ <!-- <phpcodesniffer></phpcodesniffer> -->
+ </target>
+
+ <target name="phpmd">
+ <delete dir="${dir.output}/phpmd" includeemptydirs="true" verbose="true" failonerror="true" />
+ <mkdir dir="${dir.output}/phpmd" />
+ <phpmd>
+ <fileset refid="src_files" />
+ <formatter type="html" outfile="${dir.output}/phpmd/phpmd.html"/>
+ <formatter type="xml" outfile="${dir.output}/phpmd/phpmd.xml"/>
+ </phpmd>
+ </target>
+
+ <target name="phpcpd">
+ <delete dir="${dir.output}/phpcpd" includeemptydirs="true" verbose="true" failonerror="true" />
+ <mkdir dir="${dir.output}/phpcpd" />
+ <phpcpd>
+ <fileset refid="src_files" />
+ <formatter type="pmd" outfile="${dir.output}/phpcpd/pmd.xml" />
+ <formatter type="default" outfile="${dir.output}/phpcpd/default.xml" />
+ </phpcpd>
+ </target>
+
+ <target name="phploc">
+ <exec command="phploc --log-csv ${dir.output}/logs/phploc.csv ." dir="${project.basedir}/src" passthru="true" />
+ </target>
+
+ <target name="phplint">
+ <phplint>
+ <fileset refid="src_files" />
+ </phplint>
+ </target>
+
+ <target name="phpcb" description="Aggregate tool output with PHP_CodeBrowser">
+ <exec executable="phpcb">
+ <arg value="--log" />
+ <arg path="${dir.output}/logs" />
+ <arg value="--source" />
+ <arg path="${project.basedir}/src" />
+ <arg value="--output" />
+ <arg path="${dir.output}/code-browser" />
+ </exec>
+ </target>
+
+ <target name="install-build-deps">
+ <exec command="pear install --alldeps pear.phpunit.de/PHPUnit" passthru="true" />
+ <exec command="pear install --alldeps phpunit/PHP_CodeBrowser" passthru="true" />
+ <exec command="pear install --alldeps phpunit/phploc" passthru="true" />
+ <exec command="pear install --alldeps pear.pdepend.org/PHP_Depend-beta" passthru="true" />
+ <exec command="pear install --alldeps pear.phpmd.org/PHP_PMD" passthru="true" />
+ <exec command="pear install --alldeps pear.phpunit.de/phpcpd" passthru="true" />
+ <exec command="pear install --alldeps PHP_CodeSniffer" passthru="true" />
+ <exec command="pear install --alldeps pear.phing.info/phing" passthru="true" />
+ </target>
+
+ <target name="all" depends="clean, prepare, test-init, build, report"/>
+ <target name="build" depends="phplint, prepare, test-init, test, package, package-min"/>
+ <target name="report" depends="coverage, phploc, phpcs, phpmd, phpcpd, phpdepend, phpcb"/>
+
+</project>
17 build/phar-stub-min.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+__HALT_COMPILER();
33 build/phar-stub.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+Phar::mapPhar('aws.phar');
+
+require_once 'phar://aws.phar/vendor/symfony/class-loader/Symfony/Component/ClassLoader/UniversalClassLoader.php';
+
+$classLoader = new Symfony\Component\ClassLoader\UniversalClassLoader();
+$classLoader->registerNamespaces(array(
+ 'Aws' => 'phar://aws.phar/src',
+ 'Guzzle' => 'phar://aws.phar/vendor/guzzle/guzzle/src',
+ 'Symfony\\Component\\EventDispatcher' => 'phar://aws.phar/vendor/symfony/event-dispatcher',
+ 'Doctrine' => 'phar://aws.phar/vendor/doctrine/common/lib',
+ 'Monolog' => 'phar://aws.phar/vendor/monolog/monolog/src'
+));
+$classLoader->register();
+
+return $classLoader;
+
+__HALT_COMPILER();
32 composer.json
@@ -0,0 +1,32 @@
+{
+ "name": "aws/sdk",
+ "require": {
+ "php": ">=5.3.2",
+ "ext-curl": "*",
+ "guzzle/guzzle": "2.7.*",
+ "mozilla/cacert": "*"
+ },
+ "repositories": [
+ {
+ "type": "package",
+ "package": {
+ "name": "mozilla/cacert",
+ "version": "1.8.2",
+ "dist": {
+ "url": "http://curl.haxx.se/ca/cacert.pem",
+ "type": "file"
+ }
+ }
+ }
+ ],
+ "require-dev": {
+ "symfony/class-loader": "*",
+ "doctrine/common": "*",
+ "monolog/monolog": "*"
+ },
+ "autoload": {
+ "psr-0": {
+ "Aws": "src/"
+ }
+ }
+}
37 phpunit.functional.xml.dist
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit bootstrap="./tests/bootstrap.php"
+ colors="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader">
+
+ <php>
+ <!-- If you want to run the integration tests, you will need to provide
+ the path to a service configuration file. You WILL be charged
+ for your usage if you choose to run the integration tests. -->
+ <server name="CONFIG" value="test_services.json" />
+
+ <!-- The PREFIX is added to any globally shared namespaced
+ resources that are created during integration tests -->
+ <server name="PREFIX" value="hostname" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Aws">
+ <directory>./tests/Aws/Tests</directory>
+ </testsuite>
+ </testsuites>
+
+ <!-- Only execute integration and performance tests -->
+ <groups>
+ <include>
+ <group>integration</group>
+ <group>performance</group>
+ </include>
+ </groups>
+
+</phpunit>
46 phpunit.xml.dist
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit bootstrap="./tests/bootstrap.php"
+ colors="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader">
+
+ <testsuites>
+ <testsuite name="Aws">
+ <directory>tests/Aws/Tests</directory>
+ </testsuite>
+ </testsuites>
+
+ <!-- Exclude the integration tests in regular unit tests -->
+ <groups>
+ <exclude>
+ <group>integration</group>
+ <group>performance</group>
+ </exclude>
+ </groups>
+
+ <logging>
+ <log type="junit" target="build/artifacts/logs/junit.xml" logIncompleteSkipped="false" />
+ </logging>
+
+ <filter>
+ <whitelist>
+ <directory suffix=".php">./src/Aws</directory>
+ <exclude>
+ <directory suffix="Interface.php">./src/Aws</directory>
+ <directory>./src/Aws/**/Enum</directory>
+ <directory>./src/Aws/**/Resources</directory>
+ <directory>./src/Aws/Common/Exception/InvalidArgumentException.php</directory>
+ <directory>./src/Aws/Common/Exception/RuntimeException.php</directory>
+ <directory>./src/Aws/Common/Exception/DomainException.php</directory>
+ <directory>./src/Aws/Sts/Exception</directory>
+ <directory>./src/Aws/DynamoDb/Exception</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+
+</phpunit>
90 src/Aws/Common/Aws.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common;
+
+use Guzzle\Service\Builder\ServiceBuilder;
+use Guzzle\Service\Exception\ServiceBuilderException;
+use Guzzle\Service\Exception\ServiceNotFoundException;
+
+/**
+ * Base class for interacting with web service clients
+ */
+class Aws extends ServiceBuilder
+{
+ /**
+ * @var string Current version of the SDK
+ */
+ const VERSION = '0.0.1';
+
+ /**
+ * Create a new service locator for the AWS SDK
+ *
+ * You can configure the service locator is four different ways:
+ *
+ * 1. Use the default configuration file shipped with the SDK that wires
+ * class names with service short names and specify global parameters to
+ * add to every definition (e.g. access_key_id, secret_access_key,
+ * credentials, etc)
+ *
+ * 2. Use a custom configuration file that extends the default config and
+ * supplies credentials for each service.
+ *
+ * 3. Use a custom config file that wires services to custom short names for
+ * services.
+ *
+ * 4. If you are on Amazon EC2, you can use the default configuration file
+ * and not provide any credentials so that you are using InstanceProfile
+ * credentials.
+ *
+ * @param array|string|\SimpleXMLElement $data An instantiated
+ * SimpleXMLElement containing configuration data, the full path to an
+ * .xml or .js|.json file, or when using the default configuration file,
+ * an associative array of data to use as global parameters to pass to
+ * each service as it is instantiated.
+ * @param array $globalParameters Array of global parameters to
+ * pass to every service as it is instantiated.
+ *
+ * @return Aws
+ * @throws ServiceBuilderException if a file cannot be opened
+ * @throws ServiceNotFoundException when trying to extend a missing client
+ */
+ public static function factory($config = null, array $globalParameters = null)
+ {
+ if (!$config) {
+ // If nothing is passed in, then use the default config file with
+ // Instance profile credentials
+ $config = __DIR__ . DIRECTORY_SEPARATOR . 'aws-config.json';
+ } elseif (is_array($config)) {
+ // If an array was passed, then use the default configuration file
+ // with global parameter overrides in the first argument
+ $globalParameters = $config;
+ $config = __DIR__ . DIRECTORY_SEPARATOR . 'aws-config.json';
+ }
+
+ return parent::factory($config, $globalParameters);
+ }
+
+ /**
+ * Get the full path to the default JSON service definition file
+ *
+ * @return string
+ */
+ public static function getDefaultServiceDefinition()
+ {
+ return __DIR__ . '/aws-config.json';
+ }
+}
146 src/Aws/Common/Client/AbstractClient.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common\Client;
+
+use Aws\Common\Exception\InvalidArgumentException;
+use Aws\Common\Credentials\Credentials;
+use Aws\Common\Credentials\CredentialsInterface;
+use Aws\Common\Signature\SignatureInterface;
+use Aws\Common\Signature\SignatureListener;
+use Aws\Common\Waiter\WaiterFactoryInterface;
+use Aws\Common\Waiter\WaiterClassFactory;
+use Guzzle\Common\Collection;
+use Guzzle\Service\Client;
+
+/**
+ * Abstract AWS client
+ */
+abstract class AbstractClient extends Client implements AwsClientInterface
+{
+ /**
+ * @var int Ensure that missing methods are executed using service descriptions
+ */
+ protected $magicMethodBehavior = self::MAGIC_CALL_EXECUTE;
+
+ /**
+ * @var CredentialsInterface AWS credentials
+ */
+ protected $credentials;
+
+ /**
+ * @var SignatureInterface Signature implementation of the service
+ */
+ protected $signature;
+
+ /**
+ * @var WaiterFactoryInterface Factory used to create waiter classes
+ */
+ protected $waiterFactory;
+
+ /**
+ * @param CredentialsInterface $credentials AWS credentials
+ * @param SignatureInterface $signature Signature implementation
+ * @param Collection $config Configuration options
+ */
+ public function __construct(CredentialsInterface $credentials, SignatureInterface $signature, Collection $config)
+ {
+ // Bootstrap with Guzzle
+ parent::__construct($config->get('base_url'), $config);
+ $this->credentials = $credentials;
+ $this->signature = $signature;
+
+ // Add the event listener so that requests are signed before they are sent
+ $this->getEventDispatcher()->addSubscriber(new SignatureListener($credentials, $signature));
+
+ // Resolve any config options on the client that require a client to
+ // be instantiated in order to resolve config options
+ $resolvers = $config->get('client.resolvers');
+ if ($resolvers) {
+ foreach ($resolvers as $resolver) {
+ $resolver->resolve($config, $this);
+ }
+ $config->remove('client.resolvers');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __call($method, $args = null)
+ {
+ return parent::__call(ucfirst($method), $args);
+ }
+
+ /**
+ * Get the AWS credentials used with the client
+ *
+ * @return CredentialsInterface
+ */
+ public function getCredentials()
+ {
+ return $this->credentials;
+ }
+
+ /**
+ * Wait until a resource is available or an associated waiter returns true
+ *
+ * @param string $waiter Name of the waiter in snake_case
+ * @param mixed $value Value to pass to the waiter
+ * @param array $options Options to pass to the waiter
+ *
+ * @return self
+ */
+ public function waitUntil($waiter, $value = null, array $options = array())
+ {
+ $this->getWaiterFactory()->factory($waiter)
+ ->setResourceId($value)
+ ->setClient($this)
+ ->setConfig($options)
+ ->wait();
+
+ return $this;
+ }
+
+ /**
+ * Set the waiter factory to use with the client
+ *
+ * @param WaiterFactoryInterface $waiterFactory Factory used to create waiters
+ *
+ * @return self
+ */
+ public function setWaiterFactory(WaiterFactoryInterface $waiterFactory)
+ {
+ $this->waiterFactory = $waiterFactory;
+
+ return $this;
+ }
+
+ /**
+ * Get the waiter factory used with the class
+ *
+ * @return WaiterFactoryInterface
+ */
+ protected function getWaiterFactory()
+ {
+ if (!$this->waiterFactory) {
+ $clientClass = get_class($this);
+ $this->waiterFactory = new WaiterClassFactory(substr($clientClass, 0, strrpos($clientClass, '\\')) . '\\Waiter');
+ }
+
+ return $this->waiterFactory;
+ }
+}
70 src/Aws/Common/Client/AbstractMissingFunctionOptionResolver.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common\Client;
+
+use Aws\Common\Exception\InvalidArgumentException;
+
+/**
+ * Adds base functionality to an option resolver so that if an option is
+ * missing, it can be retrieved by calling a callable function and then
+ * ensuring that the created object implements a specific interface.
+ */
+abstract class AbstractMissingFunctionOptionResolver implements OptionResolverInterface
+{
+ /**
+ * @var null|string Function to call if the option is missing
+ */
+ protected $missingFunction;
+
+ /**
+ * @var string|null Ensure that the option implements this class/interface
+ */
+ protected $mustImplement;
+
+ /**
+ * Provide a callable function to call if an expected parameter is not found
+ *
+ * @param mixed $missingFunction Callable to execute if the param is missing
+ *
+ * @return self
+ */
+ public function setMissingFunction($missingFunction)
+ {
+ if (!is_callable($missingFunction)) {
+ throw new InvalidArgumentException('Method is not callable');
+ }
+
+ $this->missingFunction = $missingFunction;
+
+ return $this;
+ }
+
+ /**
+ * Set the name of a class or interface that the option must implement if
+ * it is explicitly provided.
+ *
+ * @param string $mustImplement Name of the class or interface
+ *
+ * @return self
+ */
+ public function setMustImplement($mustImplement)
+ {
+ $this->mustImplement = $mustImplement;
+
+ return $this;
+ }
+}
59 src/Aws/Common/Client/AwsClientInterface.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common\Client;
+
+use Aws\Common\Credentials\CredentialsInterface;
+use Aws\Common\Waiter\WaiterFactoryInterface;
+use Guzzle\Service\ClientInterface;
+
+/**
+ * Interface that all AWS clients implement
+ */
+interface AwsClientInterface extends ClientInterface
+{
+ /**
+ * @var string Option key holding an exponential backoff plugin
+ */
+ const EXPONENTIAL_BACKOFF_OPTION = 'client.exponential_backoff';
+
+ /**
+ * Returns the AWS credentials associated with the client
+ *
+ * @return CredentialsInterface
+ */
+ function getCredentials();
+
+ /**
+ * Set the waiter factory to use with the client
+ *
+ * @param WaiterFactoryInterface $waiterFactory Factory used to create waiters
+ *
+ * @return self
+ */
+ function setWaiterFactory(WaiterFactoryInterface $waiterFactory);
+
+ /**
+ * Wait until a resource is available or an associated waiter returns true
+ *
+ * @param string $waiter Name of the waiter in snake_case
+ * @param mixed $value Value to pass to the waiter
+ * @param array $options Options to pass to the waiter
+ *
+ * @return self
+ */
+ function waitUntil($waiter, $value = null, array $options = array());
+}
361 src/Aws/Common/Client/ClientBuilder.php
@@ -0,0 +1,361 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common\Client;
+
+use Aws\Common\Exception\InvalidArgumentException;
+use Aws\Common\Credentials\Credentials;
+use Aws\Common\Signature\SignatureInterface;
+use Aws\Common\Exception\Parser\ExceptionParserInterface;
+use Aws\Common\Exception\Parser\DefaultXmlExceptionParser;
+use Aws\Common\Exception\NamespaceExceptionFactory;
+use Aws\Common\Exception\ExceptionListener;
+use Guzzle\Service\Inspector;
+use Guzzle\Service\Client;
+use Guzzle\Common\Collection;
+use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
+
+/**
+ * Builder for creating AWS service clients
+ */
+class ClientBuilder
+{
+ /**
+ * @var array Default client config
+ */
+ protected static $commonConfigDefaults = array(
+ 'curl.blacklist' => array(CURLOPT_ENCODING, 'header.Accept', 'header.Expect')
+ );
+
+ /**
+ * @var array Default client requirements
+ */
+ protected static $commonConfigRequirements = array(
+ 'base_url'
+ );
+
+ /**
+ * @var string The namespace of the client
+ */
+ protected $clientNamespace;
+
+ /**
+ * @var array The config options
+ */
+ protected $config = array();
+
+ /**
+ * @var array The config defaults
+ */
+ protected $configDefaults = array();
+
+ /**
+ * @var array The config requirements
+ */
+ protected $configRequirements = array();
+
+ /**
+ * @var CredentialsOptionResolver The resolver for credentials
+ */
+ protected $credentialsResolver;
+
+ /**
+ * @var SignatureOptionResolver The resolver for the signature
+ */
+ protected $signatureResolver;
+
+ /**
+ * @var SignatureInterface The signature
+ */
+ protected $signature;
+
+ /**
+ * @var array An array of client resolvers
+ */
+ protected $clientResolvers = array();
+
+ /**
+ * @var ExceptionParserInterface The Parser interface for the client
+ */
+ protected $exceptionParser;
+
+ /**
+ * Factory method for creating the client builder
+ *
+ * @param string $namespace The namespace of the client
+ *
+ * @return ClientBuilder
+ */
+ public static function factory($namespace)
+ {
+ return new static($namespace);
+ }
+
+ /**
+ * Constructs a client builder
+ *
+ * @param string $namespace The namespace of the client
+ */
+ public function __construct($namespace)
+ {
+ $this->clientNamespace = $namespace;
+ }
+
+ /**
+ * Sets the config options
+ *
+ * @param array $config The config options
+ *
+ * @return ClientBuilder
+ */
+ public function setConfig(array $config)
+ {
+ $this->config = $config;
+
+ return $this;
+ }
+
+ /**
+ * Sets the config options' defaults
+ *
+ * @param array $defaults The default values
+ *
+ * @return ClientBuilder
+ */
+ public function setConfigDefaults(array $defaults)
+ {
+ $this->configDefaults = $defaults;
+
+ return $this;
+ }
+
+ /**
+ * Sets the required config options
+ *
+ * @param array $required The required config options
+ *
+ * @return ClientBuilder
+ */
+ public function setConfigRequirements(array $required)
+ {
+ $this->configRequirements = $required;
+
+ return $this;
+ }
+
+ /**
+ * Sets the credential resolver
+ *
+ * @param CredentialsOptionResolver $credentialsResolver The credential resolver
+ *
+ * @return ClientBuilder
+ */
+ public function setCredentialsResolver(CredentialsOptionResolver $credentialsResolver)
+ {
+ $this->credentialsResolver = $credentialsResolver;
+
+ return $this;
+ }
+
+ /**
+ * Sets the signature resolver. You can use the setSignature method instead
+ * to set the signature using the default SignatureOptionResolver.
+ *
+ * @param SignatureOptionResolver $signatureResolver The signature resolver
+ *
+ * @return ClientBuilder
+ */
+ public function setSignatureResolver(SignatureOptionResolver $signatureResolver)
+ {
+ $this->signatureResolver = $signatureResolver;
+
+ return $this;
+ }
+
+ /**
+ * Sets the signature. You can use the setSignatureResolver method to set
+ * the SignatureOptionResolver instead if you need greater flexibility.
+ *
+ * @param SignatureInterface $signature The signature
+ *
+ * @return ClientBuilder
+ */
+ public function setSignature(SignatureInterface $signature)
+ {
+ $this->signature = $signature;
+
+ return $this;
+ }
+
+ /**
+ * Adds a client resolver. The most common case is adding a custom
+ * exponential backoff strategy. If an exponential backoff strategy is not
+ * provided, then a default one will be used.
+ *
+ * @param OptionResolverInterface $clientResolver A client resolver
+ *
+ * @return ClientBuilder
+ */
+ public function addClientResolver(OptionResolverInterface $clientResolver)
+ {
+ $this->clientResolvers[] = $clientResolver;
+
+ return $this;
+ }
+
+ /**
+ * Sets the exception parser. If one is not provided the builder will use
+ * the default XML exception parser.
+ *
+ * @param ExceptionParserInterface $parser The exception parser
+ *
+ * @return ClientBuilder
+ */
+ public function setExceptionParser(ExceptionParserInterface $parser)
+ {
+ $this->exceptionParser = $parser;
+
+ return $this;
+ }
+
+ /**
+ * Performs the building logic using all of the parameters that have been
+ * set and falling back to default values. Returns an instantiate service
+ * client with credentials prepared and plugins attached.
+ *
+ * @return AwsClientInterface
+ *
+ * @throws \Aws\Common\Exception\InvalidArgumentException
+ */
+ public function build()
+ {
+ // Resolve config
+ $config = Inspector::prepareConfig(
+ $this->config,
+ array_merge(self::$commonConfigDefaults, $this->configDefaults),
+ (self::$commonConfigRequirements + $this->configRequirements)
+ );
+ $this->resolveSslOptions($config);
+
+ // Resolve credentials
+ if (!$this->credentialsResolver) {
+ $this->credentialsResolver = $this->getDefaultCredentialsResolver();
+ }
+ $this->credentialsResolver->resolve($config);
+
+ // Resolve signature
+ if (!$this->signatureResolver) {
+ if (!$this->signature) {
+ throw new InvalidArgumentException('A signature has not been provided.');
+ }
+ $signature = $this->signature;
+ $this->signatureResolver = new SignatureOptionResolver(function () use ($signature) {
+ return $signature;
+ });
+ }
+ $this->signatureResolver->resolve($config);
+
+ // Add other client resolvers, like exponential backoff
+ if (!$this->hasExponentialBackoffOptionResolver()) {
+ $this->addClientResolver($this->getDefaultExponentialBackoffResolver());
+ }
+ $config->set('client.resolvers', $this->clientResolvers);
+
+ // Determine service and class name
+ $serviceName = substr($this->clientNamespace, strrpos($this->clientNamespace, '\\') + 1);
+ $clientClass = $this->clientNamespace . '\\' . $serviceName . 'Client';
+
+ // Construct the client
+ /** @var $client AwsClientInterface */
+ $client = new $clientClass($config->get('credentials'), $config->get('signature'), $config);
+
+ // Add exception marshaling so that more descriptive exception are thrown
+ $exceptionFactory = new NamespaceExceptionFactory(
+ $this->exceptionParser ?: new DefaultXmlExceptionParser(),
+ "{$this->clientNamespace}\\Exception",
+ "{$this->clientNamespace}\\Exception\\{$serviceName}Exception"
+ );
+ $client->addSubscriber(new ExceptionListener($exceptionFactory));
+
+ return $client;
+ }
+
+ /**
+ * Determine options for CA certs
+ *
+ * @param Collection $config Configuration options
+ */
+ protected function resolveSslOptions(Collection $config)
+ {
+ $certSetting = $config->get('ssl.cert');
+ if ($certSetting) {
+
+ // If set to TRUE, then use the default CA cert file
+ if ($certSetting === 'true' || $certSetting === true) {
+ $certSetting = dirname(dirname(dirname(dirname(__DIR__))))
+ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR
+ . 'mozilla' . DIRECTORY_SEPARATOR . 'cacert'
+ . DIRECTORY_SEPARATOR . 'cacert.pem';
+ }
+
+ // Enable SSL certificate verification using the Mozilla cert
+ $config->set('curl.CURLOPT_CAINFO', $certSetting);
+ }
+ }
+
+ /**
+ * Returns the default credential resolver for a client
+ *
+ * @return CredentialsOptionResolver
+ */
+ protected function getDefaultCredentialsResolver()
+ {
+ return new CredentialsOptionResolver(function (Collection $config) {
+ return Credentials::factory($config->getAll(array_keys(Credentials::getConfigDefaults())));
+ });
+ }
+
+ /**
+ * Returns the default exponential backoff plugin for a client
+ *
+ * @return ExponentialBackoffOptionResolver
+ */
+ protected function getDefaultExponentialBackoffResolver()
+ {
+ return new ExponentialBackoffOptionResolver(function() {
+ return new ExponentialBackoffPlugin();
+ });
+ }
+
+ /**
+ * Determines whether or not an exponential backoff plugin has been added to the builder
+ *
+ * @return bool
+ */
+ protected function hasExponentialBackoffOptionResolver()
+ {
+ $hasExponentialBackoff = false;
+
+ foreach ($this->clientResolvers as $resolver) {
+ if ($resolver instanceof ExponentialBackoffOptionResolver) {
+ $hasExponentialBackoff = true;
+ break;
+ }
+ }
+
+ return $hasExponentialBackoff;
+ }
+}
95 src/Aws/Common/Client/CredentialsOptionResolver.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common\Client;
+
+use Aws\Common\Credentials\Credentials;
+use Aws\Common\Credentials\CredentialsInterface;
+use Aws\Common\Credentials\RefreshableInstanceProfileCredentials;
+use Aws\Common\Exception\InvalidArgumentException;
+use Guzzle\Common\Collection;
+
+/**
+ * Configures credentials for a configuration collection.
+ *
+ * If an 'access_key_id' and 'secret_access_key' are provided, then this
+ * resolver will instantiate a default credentials object for the config.
+ *
+ * If a 'credential' option is provided, then this resolver will ensure that the
+ * 'credential' option is valid and implements
+ * {@see Aws\Common\Credentials\CredentialsInterface}.
+ *
+ * If none of the above are provided, then this resolver will add credentials
+ * to the configuration that attempt to get credentials from an Amazon EC2
+ * instance profile server.
+ */
+class CredentialsOptionResolver extends AbstractMissingFunctionOptionResolver
+{
+ /**
+ * @param string $missingFunction Provide a callable function to call if the
+ * 'credentials' parameter is not set.
+ * @param string $mustImplement Provide the name of a class or interface
+ * that the 'signature' option must extend if
+ * set
+ */
+ public function __construct(
+ $missingFunction = null,
+ $mustImplement = 'Aws\\Common\\Credentials\\CredentialsInterface')
+ {
+ if ($missingFunction) {
+ $this->setMissingFunction($missingFunction);
+ } else {
+ $this->setMissingFunction(array($this, 'defaultMissingFunction'));
+ }
+ $this->setMustImplement($mustImplement);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve(Collection $config, AwsClientInterface $client = null)
+ {
+ $credentials = $config->get('credentials');
+
+ if (!$credentials && $this->missingFunction) {
+ $credentials = call_user_func($this->missingFunction, $config);
+ $config->set('credentials', $credentials);
+ }
+
+ // Ensure that the credentials are valid
+ if ($credentials && !($credentials instanceof $this->mustImplement)) {
+ throw new InvalidArgumentException('The credentials you provided do not implement ' . $this->mustImplement);
+ }
+ }
+
+ /**
+ * Default method to execute when credentials are not specified
+ *
+ * @param Collection $config Config options
+ *
+ * @return CredentialsInterface
+ */
+ protected function defaultMissingFunction(Collection $config)
+ {
+ if ($config->get('access_key_id') && $config->get('secret_access_key')) {
+ // Credentials were not provided, so create them using keys
+ return Credentials::factory($config->getAll());
+ }
+
+ // Attempt to get credentials from the EC2 instance profile server
+ return new RefreshableInstanceProfileCredentials(new Credentials('', '', '', 1));
+ }
+}
68 src/Aws/Common/Client/ExponentialBackoffOptionResolver.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common\Client;
+
+use Aws\Common\Client\AwsClientInterface;
+use Aws\Common\Exception\InvalidArgumentException;
+use Guzzle\Common\Collection;
+use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
+
+/**
+ * Ensures that a valid 'client.exponential_backoff' option is present in the
+ * configuration collection. If the option is not present, this resolver
+ * executes a callback to add an {@see ExponentialBackoff} plugin to the config.
+ */
+class ExponentialBackoffOptionResolver extends AbstractMissingFunctionOptionResolver
+{
+ /**
+ * @param string $missingFunction Provide a callable function to call if the
+ * 'client.exponential_backoff' parameter is not set
+ */
+ public function __construct($missingFunction = null)
+ {
+ if ($missingFunction) {
+ $this->setMissingFunction($missingFunction);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve(Collection $config, AwsClientInterface $client = null)
+ {
+ // A user can inject the plugin in their options array or have one
+ // created for them by default
+ $plugin = $config->get(AwsClientInterface::EXPONENTIAL_BACKOFF_OPTION);
+ if (!$plugin && $this->missingFunction) {
+ $plugin = call_user_func($this->missingFunction, $config, $client);
+ $config->set(AwsClientInterface::EXPONENTIAL_BACKOFF_OPTION, $plugin);
+ }
+
+ // Ensure that the plugin implements the correct interface
+ if ($plugin && !($plugin instanceof ExponentialBackoffPlugin)) {
+ throw new InvalidArgumentException(
+ 'client.exponential_backoff must be an instance of ' .
+ 'Guzzle\\Http\\Plugin\\ExpontialBackoffPlugin'
+ );
+ }
+
+ // Attach the ExponentialBackoffPlugin to the client
+ if ($client) {
+ $client->getEventDispatcher()->addSubscriber($plugin, -255);
+ }
+ }
+}
37 src/Aws/Common/Client/OptionResolverInterface.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+namespace Aws\Common\Client;
+
+use Aws\Common\Exception\InvalidArgumentException;
+use Guzzle\Common\Collection;
+
+/**
+ * Validates and prepares configuration options for a client
+ */
+interface OptionResolverInterface
+{
+ /**
+ * Ensures that a configuration collection has required parameters and
+ * if not tries to add default values based on context,
+ *
+ * @param Collection $config Configuration data to check and update
+ * @param AwsClientInterface $client Client to pass to the resolver
+ *
+ * @throws InvalidArgumentException if the provided configuration is invalid
+ */
+ function resolve(Collection $config, AwsClientInterface $client = null);
+}
82 src/Aws/Common/Client/SignatureOptionResolver.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *