├── LICENSE
├── NOTICE
├── aws-greengrass-core-sdk
├── index.js
├── iotdata.js
├── lambda.js
├── package.json
├── secretsmanager.js
├── stream-manager
│ ├── client.js
│ ├── data
│ │ └── index.js
│ ├── exceptions.js
│ ├── index.js
│ ├── util.js
│ └── utilInternal.js
└── util.js
├── docs
├── .nojekyll
├── aws-greengrass-core-sdk.IotData.html
├── aws-greengrass-core-sdk.Lambda.html
├── aws-greengrass-core-sdk.SecretsManager.html
├── aws-greengrass-core-sdk.StreamManager.AppendMessageRequest.html
├── aws-greengrass-core-sdk.StreamManager.AppendMessageResponse.html
├── aws-greengrass-core-sdk.StreamManager.AssetPropertyValue.html
├── aws-greengrass-core-sdk.StreamManager.ConnectRequest.html
├── aws-greengrass-core-sdk.StreamManager.ConnectResponse.html
├── aws-greengrass-core-sdk.StreamManager.CreateMessageStreamRequest.html
├── aws-greengrass-core-sdk.StreamManager.CreateMessageStreamResponse.html
├── aws-greengrass-core-sdk.StreamManager.DeleteMessageStreamRequest.html
├── aws-greengrass-core-sdk.StreamManager.DeleteMessageStreamResponse.html
├── aws-greengrass-core-sdk.StreamManager.DescribeMessageStreamRequest.html
├── aws-greengrass-core-sdk.StreamManager.DescribeMessageStreamResponse.html
├── aws-greengrass-core-sdk.StreamManager.EventType.html
├── aws-greengrass-core-sdk.StreamManager.ExportDefinition.html
├── aws-greengrass-core-sdk.StreamManager.ExportFormat.html
├── aws-greengrass-core-sdk.StreamManager.HTTPConfig.html
├── aws-greengrass-core-sdk.StreamManager.IoTAnalyticsConfig.html
├── aws-greengrass-core-sdk.StreamManager.IoTSiteWiseConfig.html
├── aws-greengrass-core-sdk.StreamManager.KinesisConfig.html
├── aws-greengrass-core-sdk.StreamManager.ListStreamsRequest.html
├── aws-greengrass-core-sdk.StreamManager.ListStreamsResponse.html
├── aws-greengrass-core-sdk.StreamManager.Message.html
├── aws-greengrass-core-sdk.StreamManager.MessageFrame.html
├── aws-greengrass-core-sdk.StreamManager.MessageStreamDefinition.html
├── aws-greengrass-core-sdk.StreamManager.MessageStreamInfo-MessageStreamInfo._exportStatuses.html
├── aws-greengrass-core-sdk.StreamManager.MessageStreamInfo-MessageStreamInfo._storageStatus.html
├── aws-greengrass-core-sdk.StreamManager.MessageStreamInfo.html
├── aws-greengrass-core-sdk.StreamManager.Operation.html
├── aws-greengrass-core-sdk.StreamManager.Persistence.html
├── aws-greengrass-core-sdk.StreamManager.PutAssetPropertyValueEntry.html
├── aws-greengrass-core-sdk.StreamManager.Quality.html
├── aws-greengrass-core-sdk.StreamManager.ReadMessagesOptions.html
├── aws-greengrass-core-sdk.StreamManager.ReadMessagesRequest.html
├── aws-greengrass-core-sdk.StreamManager.ReadMessagesResponse.html
├── aws-greengrass-core-sdk.StreamManager.ResponseStatusCode.html
├── aws-greengrass-core-sdk.StreamManager.S3ExportTaskDefinition.html
├── aws-greengrass-core-sdk.StreamManager.S3ExportTaskExecutorConfig.html
├── aws-greengrass-core-sdk.StreamManager.Status.html
├── aws-greengrass-core-sdk.StreamManager.StatusConfig.html
├── aws-greengrass-core-sdk.StreamManager.StatusContext.html
├── aws-greengrass-core-sdk.StreamManager.StatusLevel.html
├── aws-greengrass-core-sdk.StreamManager.StatusMessage.html
├── aws-greengrass-core-sdk.StreamManager.StrategyOnFull.html
├── aws-greengrass-core-sdk.StreamManager.StreamManagerClient.html
├── aws-greengrass-core-sdk.StreamManager.TimeInNanos.html
├── aws-greengrass-core-sdk.StreamManager.TraceableRequest.html
├── aws-greengrass-core-sdk.StreamManager.UnknownOperationError.html
├── aws-greengrass-core-sdk.StreamManager.UpdateMessageStreamRequest.html
├── aws-greengrass-core-sdk.StreamManager.UpdateMessageStreamResponse.html
├── aws-greengrass-core-sdk.StreamManager.Variant.html
├── aws-greengrass-core-sdk.StreamManager.VersionInfo.html
├── aws-greengrass-core-sdk.StreamManager.html
├── aws-greengrass-core-sdk.html
├── fonts
│ ├── OpenSans-Bold-webfont.eot
│ ├── OpenSans-Bold-webfont.svg
│ ├── OpenSans-Bold-webfont.woff
│ ├── OpenSans-BoldItalic-webfont.eot
│ ├── OpenSans-BoldItalic-webfont.svg
│ ├── OpenSans-BoldItalic-webfont.woff
│ ├── OpenSans-Italic-webfont.eot
│ ├── OpenSans-Italic-webfont.svg
│ ├── OpenSans-Italic-webfont.woff
│ ├── OpenSans-Light-webfont.eot
│ ├── OpenSans-Light-webfont.svg
│ ├── OpenSans-Light-webfont.woff
│ ├── OpenSans-LightItalic-webfont.eot
│ ├── OpenSans-LightItalic-webfont.svg
│ ├── OpenSans-LightItalic-webfont.woff
│ ├── OpenSans-Regular-webfont.eot
│ ├── OpenSans-Regular-webfont.svg
│ └── OpenSans-Regular-webfont.woff
├── global.html
├── index.html
├── index.js.html
├── iotdata.js.html
├── lambda.js.html
├── scripts
│ ├── linenumber.js
│ └── prettify
│ │ ├── Apache-License-2.0.txt
│ │ ├── lang-css.js
│ │ └── prettify.js
├── secretsmanager.js.html
├── stream-manager_client.js.html
├── stream-manager_data_index.js.html
├── stream-manager_index.js.html
├── stream-manager_util.js.html
└── styles
│ ├── jsdoc-default.css
│ ├── prettify-jsdoc.css
│ └── prettify-tomorrow.css
├── greengrassExamples
├── HelloWorld
│ └── index.js
├── LambdaInvoke
│ ├── invokee.js
│ ├── invokerbinary.js
│ └── invokerjson.js
├── ShadowOperations
│ └── index.js
├── StreamManagerIoTSiteWise
│ └── index.js
├── StreamManagerKinesis
│ └── index.js
├── StreamManagerS3
│ └── index.js
└── TES
│ ├── README
│ └── index.js
└── readme.md
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | AWS Greengrass Core SDK for JavaScript
2 | Copyright 2012-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 |
4 | This product includes software developed at
5 | Amazon Web Services, Inc. (http://aws.amazon.com/).
6 |
7 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 | exports.GreengrassInterfaceVersion = '1.5';
5 |
6 | /**
7 | * @namespace aws-greengrass-core-sdk
8 | */
9 |
10 | const fail = (name, error) => {
11 | console.error(`Unable to load aws-greengrass-core-sdk.${name} due to: `, error);
12 | };
13 |
14 | try {
15 | exports.Lambda = require('./lambda');
16 | } catch (e) {
17 | fail('Lambda', e);
18 | }
19 | try {
20 | exports.IotData = require('./iotdata');
21 | } catch (e) {
22 | fail('IotData', e);
23 | }
24 | try {
25 | exports.SecretsManager = require('./secretsmanager');
26 | } catch (e) {
27 | fail('SecretsManager', e);
28 | }
29 | try {
30 | exports.StreamManager = require('./stream-manager');
31 | } catch (e) {
32 | fail('StreamManager', e);
33 | }
34 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/iotdata.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | const { Buffer } = require('buffer');
6 |
7 | const GreengrassCommon = require('aws-greengrass-common-js');
8 | const Lambda = require('./lambda');
9 | const Util = require('./util');
10 |
11 | const { envVars } = GreengrassCommon;
12 | const { MY_FUNCTION_ARN } = envVars;
13 | const { SHADOW_FUNCTION_ARN } = envVars;
14 | const { ROUTER_FUNCTION_ARN } = envVars;
15 |
16 | /**
17 | * Constructs a service interface object. Each API operation is exposed as a function on service.
18 | *
19 | * @class
20 | * @memberOf aws-greengrass-core-sdk
21 | *
22 | * @example
Sending a Request Using IotData
23 | * var iotdata = new GG.IotData();
24 | * iotdata.getThingShadow(params, function (err, data) {
25 | * if (err) console.log(err, err.stack); // an error occurred
26 | * else console.log(data); // successful response
27 | * });
28 | */
29 | class IotData {
30 | /**
31 | * Constructs a service object. This object has one method for each API operation.
32 | *
33 | * @example
Constructing a IotData object
34 | * var iotdata = new GG.IotData();
35 | */
36 | constructor() {
37 | this.lambda = new Lambda();
38 | }
39 |
40 | /**
41 | * Called when a response from the service is returned.
42 | *
43 | * @callback iotDataCallback
44 | * @param err {Error} The error object returned from the request. Set to null if the request is successful.
45 | * @param data {Object} The de-serialized data returned from the request. Set to null if a request error occurs.
46 | * @param data.payload {Buffer|TypedArray|Blob|String} The state information in JSON format
47 | */
48 | /**
49 | * Gets the thing shadow for the specified thing.
50 | *
51 | * @param params {Object}
52 | * @param params.thingName {String} The name of the thing.
53 | * @param callback {iotDataCallback} The callback.
54 | *
55 | * @example
Calling the getThingShadow operation
56 | * var params = {
57 | * thingName: 'STRING_VALUE' // required
58 | * };
59 | * iotdata.getThingShadow(params, function(err, data) {
60 | * if (err) console.log(err, err.stack); // an error occurred
61 | * else console.log(data); // successful response
62 | * });
63 | */
64 | getThingShadow(params, callback) {
65 | const thingName = Util.getParameter(params, 'thingName');
66 | if (thingName === undefined) {
67 | callback(new Error('"thingName" is a required parameter.'), null);
68 | return;
69 | }
70 |
71 | const payload = '';
72 | this._shadowOperation('get', thingName, payload, callback);
73 | }
74 |
75 | /**
76 | * Updates the thing shadow for the specified thing.
77 | *
78 | * @param params {Object}
79 | * @param params.thingName {String} The name of the thing.
80 | * @param params.payload {String} The state information as a JSON string.
81 | * @param callback {iotDataCallback} The callback.
82 | *
83 | * @example
Calling the updateThingShadow operation
84 | * var params = {
85 | * payload: 'Proper JSON data', // required
86 | * thingName: 'STRING_VALUE' // required
87 | * };
88 | * iotdata.updateThingShadow(params, function(err, data) {
89 | * if (err) console.log(err, err.stack); // an error occurred
90 | * else console.log(data); // successful response
91 | * });
92 | */
93 | updateThingShadow(params, callback) {
94 | const thingName = Util.getParameter(params, 'thingName');
95 | if (thingName === undefined) {
96 | callback(new Error('"thingName" is a required parameter.'), null);
97 | return;
98 | }
99 |
100 | const payload = Util.getParameter(params, 'payload');
101 | if (payload === undefined) {
102 | callback(new Error('"payload" is a required parameter.'), null);
103 | return;
104 | }
105 |
106 | this._shadowOperation('update', thingName, payload, callback);
107 | }
108 |
109 | /**
110 | * Call shadow lambda to delete the shadow state.
111 | *
112 | * @param params {Object}
113 | * @param params.thingName {String} The name of the thing whose shadow should be deleted.
114 | * @param callback {iotDataCallback} The callback.
115 | */
116 | deleteThingShadow(params, callback) {
117 | const thingName = Util.getParameter(params, 'thingName');
118 | if (thingName === undefined) {
119 | callback(new Error('"thingName" is a required parameter.'), null);
120 | return;
121 | }
122 |
123 | const payload = '';
124 | this._shadowOperation('delete', thingName, payload, callback);
125 | }
126 |
127 | /**
128 | * Publishes a message within Greengrass.
129 | *
130 | * @param params {Object}
131 | * @param params.topic {String} The name of the MQTT topic.
132 | * @param params.payload {Buffer|TypedArray|Blob|String} The payload to be sent.
133 | * @param params.queueFullPolicy {'AllOrError'|'BestEffort'} Specify whether to enforce message delivery to all destinations. Options are 'AllOrError' and 'BestEffort'. Defaults to 'BestEffort' when omitted.
134 | * @param callback {iotDataCallback} The callback.
135 | *
136 | * @example
24 | * var lambda = new GG.Lambda();
25 | */
26 | constructor() {
27 | this.ipc = new IPCClient(AUTH_TOKEN);
28 | }
29 |
30 | /**
31 | * Called when a response from the service is returned.
32 | *
33 | * @callback lambdaCallback
34 | * @param err {Error} The error object returned from the request. Set to null if the request is successful.
35 | * @param data {Object} The de-serialized data returned from the request. Set to null if a request error occurs.
36 | * @param data.StatusCode {Integer} The HTTP status code will be in the 200 range for successful request. For the RequestResponse invocation type this status code will be 200.
37 | * For the Event invocation type this status code will be 202.
38 | * @param data.FunctionError {String} Indicates whether an error occurred while executing the Lambda function. If an error occurred this field will have one of two values; Handled or Unhandled.
39 | * Handled errors are errors that are reported by the function while the Unhandled errors are those detected and reported by AWS Lambda.
40 | * Unhandled errors include out of memory errors and function timeouts. For information about how to report an Handled error,
41 | * see Programming Model.
42 | * @param data.Payload {Buffer|TypedArray|Blob|String} It is the result returned by the Lambda function. This is present only if the invocation type is RequestResponse.
43 | * In the event of a function error this field contains a message describing the error. For the Handled errors the Lambda function will report this message. For Unhandled errors AWS Lambda reports the message.
44 | */
45 |
46 | /**
47 | * Invokes a specific Lambda function.
48 | * In Greengrass, version of the Lambda which you would like to invoke needs to be provided.
49 | *
50 | * @param params {Object}
51 | * @param params.FunctionName {String} The Lambda function name. You can specify Amazon Resource Name (ARN) of the function (for example, arn:aws:lambda:us-west-2:account-id:function:ThumbNail).
52 | * @param params.InvocationType {String?} By default, the Invoke API assumes RequestResponse invocation type.
53 | * You can optionally request asynchronous execution by specifying Event as the InvocationType. Possible values include:
54 | *
"Event"
"RequestResponse"
55 | * @param params.ClientContext {String?} Using the ClientContext you can pass client-specific information to the Lambda function you are invoking.
56 | * You can then process the client information in your Lambda function as you choose through the context variable.
57 | * For an example of a ClientContext JSON, see the main page or an example folder for an example.
58 | * The ClientContext JSON must be base64-encoded.
59 | * @param params.Payload {Buffer|TypedArray|Blob|String} Payload that you want to provide to your Lambda function as input.
60 | * @param params.Qualifier {String?} You can use this optional parameter to specify a Lambda function version if it was not included in the FunctionName field.
61 | * If you specify a function version, the API uses the qualified function ARN to invoke a specific Lambda function.
62 | * If you don't provide this parameter, then the API uses the FunctionName field only. If it does not have a version number of the target lambda, the call will fail.
63 | * @param callback {lambdaCallback} The callback.
64 | *
65 | * @example
81 | * var params = {
82 | * FunctionName: 'STRING_VALUE', // required
83 | * ClientContext: 'STRING_VALUE',
84 | * InvocationType: Event | RequestResponse,
85 | * Payload: ,
86 | * Qualifier: 'STRING_VALUE'
87 | * };
88 | * lambda.invoke(params, function(err, data) {
89 | * if (err) console.log(err, err.stack); // an error occurred
90 | * else console.log(data); // successful response
91 | * });
92 | */
93 | invoke(params, callback) {
94 | const functionName = Util.getParameter(params, 'FunctionName');
95 | if (functionName === undefined) {
96 | callback(new Error('"FunctionName" is a required parameter'), null);
97 | return;
98 | }
99 |
100 | let arnFields;
101 | try {
102 | arnFields = new GreengrassCommon.FunctionArnFields(functionName);
103 | } catch (e) {
104 | callback(new Error(`FunctionName is malformed: ${e}`), null);
105 | return;
106 | }
107 |
108 | let invocationType;
109 | if (params.InvocationType === undefined || params.InvocationType === null) {
110 | invocationType = 'RequestResponse';
111 | } else {
112 | invocationType = params.InvocationType;
113 | }
114 |
115 | if (invocationType !== 'Event' && invocationType !== 'RequestResponse') {
116 | callback(new Error(`InvocationType '${invocationType}' is incorrect, should be 'Event' or 'RequestResponse'`), null);
117 | return;
118 | }
119 |
120 | const clientContext = params.ClientContext ? params.ClientContext : '';
121 | const payload = params.Payload;
122 | const qualifier = params.Qualifier;
123 |
124 | if (!Util.isValidQualifier(qualifier)) {
125 | callback(new Error(`Qualifier '${qualifier}' is incorrect`), null);
126 | return;
127 | }
128 |
129 | const qualifierInternal = arnFields.qualifier;
130 |
131 | // generate the right full function arn with qualifier
132 | if (qualifierInternal && qualifier && qualifierInternal !== qualifier) {
133 | callback(new Error(`Qualifier '${qualifier}' does not match the version in FunctionName`), null);
134 | return;
135 | }
136 |
137 | const finalQualifier = qualifierInternal === undefined || qualifierInternal == null ? qualifier : qualifierInternal;
138 |
139 | let functionArn;
140 | if (typeof GreengrassCommon.buildFunctionArn === 'function') {
141 | // GGC v1.9.0 or newer
142 | functionArn = GreengrassCommon.buildFunctionArn(
143 | arnFields.unqualifiedArn,
144 | finalQualifier,
145 | );
146 | } else {
147 | // older version of GGC
148 | throw new Error('Function buildFunctionArn not found. buildFunctionArn is introduced in GGC v1.9.0. '
149 | + 'Please check your GGC version.');
150 | }
151 |
152 | // verify client context is base64 encoded
153 | if (Object.prototype.hasOwnProperty.call(params, 'ClientContext')) {
154 | const cxt = params.ClientContext;
155 | if (!Util.isValidContext(cxt)) {
156 | callback(new Error('Client Context is invalid'), null);
157 | return;
158 | }
159 | }
160 |
161 | logger.debug(`Invoking local lambda ${functionArn} with payload ${payload} and client context ${clientContext}`);
162 |
163 | this.ipc.postWork(functionArn, payload, clientContext, invocationType, (postWorkErr, invocationId) => {
164 | if (postWorkErr) {
165 | logger.error(`Failed to invoke function due to ${postWorkErr}`);
166 | callback(postWorkErr, null);
167 | return;
168 | }
169 |
170 | if (invocationType === 'RequestResponse') {
171 | this.ipc.getWorkResult(functionArn, invocationId, (getWorkResultErr, body, functionErr, statusCode) => {
172 | if (getWorkResultErr) {
173 | logger.error(`Failed to get work result due to ${getWorkResultErr}`);
174 | callback(getWorkResultErr, null);
175 | return;
176 | }
177 | const data = {
178 | FunctionError: functionErr,
179 | StatusCode: statusCode,
180 | Payload: body,
181 | };
182 | callback(null, data);
183 | });
184 | } else {
185 | callback(null, invocationId);
186 | }
187 | });
188 | }
189 | }
190 |
191 | module.exports = Lambda;
192 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aws-greengrass-core-sdk",
3 | "version": "1.7.0",
4 | "main": "index.js",
5 | "dependencies": {
6 | "cbor": "5.0.1"
7 | },
8 | "license": "Apache-2.0",
9 | "author": {
10 | "name": "Amazon Web Services",
11 | "url": "https://aws.amazon.com"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/aws/aws-greengrass-core-sdk-js"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/secretsmanager.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 | const { Buffer } = require('buffer');
5 |
6 | const GreengrassCommon = require('aws-greengrass-common-js');
7 | const Lambda = require('./lambda');
8 | const Util = require('./util');
9 |
10 | const KEY_SECRET_ID = 'SecretId';
11 | const KEY_VERSION_ID = 'VersionId';
12 | const KEY_VERSION_STAGE = 'VersionStage';
13 | const KEY_SECRET_ARN = 'ARN';
14 | const KEY_SECRET_NAME = 'Name';
15 | const KEY_CREATED_DATE = 'CreatedDate';
16 | const KEY_JSON_RESULT_FLAG = 'DeStringifyResultFlag';
17 |
18 | const { envVars } = GreengrassCommon;
19 | const { SECRETS_MANAGER_FUNCTION_ARN } = envVars;
20 |
21 | /**
22 | * Constructs a service interface object. Each API operation is exposed as a function on service.
23 | * @class
24 | * @memberOf aws-greengrass-core-sdk
25 | */
26 | class SecretsManager {
27 | /**
28 | * Constructs a service object. This object has one method for each API operation.
29 | *
30 | * @example
Constructing a SecretsManager object
31 | * var secretsmanager = new GG.SecretsManager();
32 | */
33 | constructor() {
34 | this.lambda = new Lambda();
35 | }
36 |
37 | /**
38 | * Called when a response from the service is returned.
39 | *
40 | * @callback secretsManagerCallback
41 | * @param err {Error} The error object returned from the request. Set to null if the request is successful.
42 | * @param data {Object|String} data returned from the request. Return type is decided on DeStringifyResultFlag flag in request. Set to null if a request error occurs.
43 | * @param data.ARN {String} The ARN of the secret.
44 | * @param data.Name {String} The friendly name of the secret.
45 | * @param data.VersionId {String} The unique identifier of this version of the secret.
46 | * @param data.SecretBinary {Buffer|TypedArray|Blob|String} The decrypted part of the protected secret information that was originally provided as binary data in the form of a byte array.
47 | * The response parameter represents the binary data as a base64-encoded string.
48 | * @param data.SecretString {String} The decrypted part of the protected secret information that was originally provided as a string.
49 | * @param data.VersionStages {String[]} Specifies the secret version that you want to retrieve by the staging label attached to the version.
50 | * Staging labels are used to keep track of different versions during the rotation process.
51 | */
52 |
53 | /**
54 | * Retrieves a specific local secret value.
55 | *
56 | * @param params {Object}
57 | * @param params.SecretId {String} Specifies the secret containing the version that you want to retrieve. You can specify either the Amazon Resource Name (ARN) or the friendly name of the secret.
58 | * @param params.VersionStage {String} Specifies the secret version that you want to retrieve by the staging label attached to the version.
59 | * Staging labels are used to keep track of different versions during the rotation process.
60 | * @param params.DeStringifyResultFlag {boolean} Optional Flag to decide the return type from getSecretValue. If set, it returns de-serialized data object, otherwise it returns stringified response.
61 | * @param callback {secretsManagerCallback} The callback.
62 | *
63 | * @example
Retrieving a local secret value
64 | * // This operation retrieves a local secret value
65 | *
66 | * var params = {
67 | * SecretId: "STRING_VALUE",
68 | * VersionStage: "STRING_VALUE"
69 | * };
70 | * secretsmanager.getSecretValue(params, function(err, data) {
71 | * if (err) console.log(err, err.stack); // an error occurred
72 | * else console.log(data); // successful response
73 | * });
74 | */
75 | getSecretValue(params, callback) {
76 | const secretId = Util.getParameter(params, KEY_SECRET_ID);
77 | const versionId = Util.getParameter(params, KEY_VERSION_ID);
78 | const versionStage = Util.getParameter(params, KEY_VERSION_STAGE);
79 | const isJSONResultFlagSet = Util.getParameter(params, KEY_JSON_RESULT_FLAG);
80 |
81 | if (secretId === undefined) {
82 | callback(new Error(`"${KEY_SECRET_ID}" is a required parameter`), null);
83 | return;
84 | }
85 | // TODO: Remove this once we support query by VersionId
86 | if (versionId !== undefined) {
87 | callback(new Error('Query by VersionId is not yet supported'), null);
88 | return;
89 | }
90 | if (versionId !== undefined && versionStage !== undefined) {
91 | callback(new Error('VersionId and VersionStage cannot both be specified at the same time'), null);
92 | return;
93 | }
94 |
95 | const getSecretValueRequestBytes = SecretsManager._generateGetSecretValueRequestBytes(secretId, versionId, versionStage);
96 |
97 | const invokeParams = {
98 | FunctionName: SECRETS_MANAGER_FUNCTION_ARN,
99 | Payload: getSecretValueRequestBytes,
100 | };
101 |
102 | console.log(`Getting secret value from secrets manager: ${getSecretValueRequestBytes}`);
103 |
104 | this.lambda.invoke(invokeParams, (err, data) => {
105 | if (err) {
106 | callback(err, null); // an error occurred
107 | } else if (SecretsManager._is200Response(data.Payload)) {
108 | // successful response
109 | if (isJSONResultFlagSet) {
110 | callback(null, JSON.parse(data.Payload));
111 | }
112 | callback(null, data.Payload);
113 | } else {
114 | callback(new Error(JSON.stringify(data.Payload)), null); // error response
115 | }
116 | });
117 | }
118 |
119 | static _generateGetSecretValueRequestBytes(secretId, versionId, versionStage) {
120 | const request = {
121 | SecretId: secretId,
122 | };
123 |
124 | if (versionStage !== undefined) {
125 | request.VersionStage = versionStage;
126 | }
127 |
128 | if (versionId !== undefined) {
129 | request.VersionId = versionId;
130 | }
131 |
132 | return Buffer.from(JSON.stringify(request));
133 | }
134 |
135 | static _is200Response(payload) {
136 | const hasSecretArn = this._stringContains(payload, KEY_SECRET_ARN);
137 | const hasSecretName = this._stringContains(payload, KEY_SECRET_NAME);
138 | const hasVersionId = this._stringContains(payload, KEY_VERSION_ID);
139 | const hasCreatedDate = this._stringContains(payload, KEY_CREATED_DATE);
140 |
141 | return hasSecretArn && hasSecretName && hasVersionId && hasCreatedDate;
142 | }
143 |
144 | static _stringContains(src, target) {
145 | return src.indexOf(target) > -1;
146 | }
147 | }
148 |
149 | module.exports = SecretsManager;
150 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/stream-manager/exceptions.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | // eslint-disable-next-line max-classes-per-file
6 | class StreamManagerException extends Error {
7 | constructor(message = '', status = null, requestId = null) {
8 | super(message);
9 | this.status = status;
10 | this.requestId = requestId;
11 | }
12 | }
13 |
14 | class ClientException extends StreamManagerException {}
15 | class ConnectFailedException extends ClientException {}
16 | class InvalidRequestException extends StreamManagerException {}
17 | class MessageStoreReadErrorException extends StreamManagerException {}
18 | class NotEnoughMessagesException extends StreamManagerException {}
19 | class RequestPayloadTooLargeException extends StreamManagerException {}
20 | class ResourceNotFoundException extends StreamManagerException {}
21 | class ResponsePayloadTooLargeException extends StreamManagerException {}
22 | class ServerOutOfMemoryException extends StreamManagerException {}
23 | class ServerTimeoutException extends StreamManagerException {}
24 | class UnauthorizedException extends StreamManagerException {}
25 | class UnknownFailureException extends StreamManagerException {}
26 | class UpdateFailedException extends StreamManagerException {}
27 | class UnknownOperationException extends StreamManagerException {}
28 | class UpdateNotAllowedException extends InvalidRequestException {}
29 | class ValidationException extends ClientException {}
30 |
31 | module.exports = {
32 | ClientException,
33 | ConnectFailedException,
34 | InvalidRequestException,
35 | MessageStoreReadErrorException,
36 | NotEnoughMessagesException,
37 | RequestPayloadTooLargeException,
38 | ResourceNotFoundException,
39 | ResponsePayloadTooLargeException,
40 | ServerOutOfMemoryException,
41 | ServerTimeoutException,
42 | StreamManagerException,
43 | UnauthorizedException,
44 | UnknownFailureException,
45 | ValidationException,
46 | UpdateFailedException,
47 | UpdateNotAllowedException,
48 | UnknownOperationException,
49 | };
50 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/stream-manager/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /**
6 | * @namespace aws-greengrass-core-sdk.StreamManager
7 | */
8 |
9 | module.exports = require('./client');
10 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/stream-manager/util.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-restricted-syntax */
2 | /*
3 | * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | */
5 |
6 | const exceptions = require('./exceptions');
7 | const utilInternal = require('./utilInternal');
8 |
9 | /**
10 | * Validate And Serialize an instance of class to Json bytes
11 | * @param o a instance object
12 | * @return byte array
13 | * @exception throws ValidationException
14 | */
15 | const validateAndSerializeToJsonBytes = (o) => {
16 | const validation = utilInternal.isInvalid(o);
17 | if (validation) {
18 | throw new exceptions.ValidationException(validation);
19 | }
20 | return utilInternal.serializeToJsonWithEmptyArrayAsNull(o.asMap());
21 | };
22 |
23 |
24 | /**
25 | * Deserialize the json byte array to an instance of class
26 | * @param bytes a bytes array
27 | * @param type instance type
28 | * @return object
29 | */
30 | const deserializeJsonBytesToObj = (bytes, type) => type.fromMap(JSON.parse(bytes.toString('utf-8')));
31 |
32 | module.exports = {
33 | validateAndSerializeToJsonBytes,
34 | deserializeJsonBytesToObj,
35 | };
36 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/stream-manager/utilInternal.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-restricted-syntax */
2 | /*
3 | * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | */
5 |
6 | const smData = require('aws-greengrass-core-sdk/stream-manager/data');
7 | const exceptions = require('./exceptions');
8 |
9 | // eslint-disable-next-line no-bitwise
10 | const MAX_PACKET_SIZE = 1 << 30;
11 | const LENGTH_FIELD_SIZE_BYTES = 4;
12 | const OP_FIELD_SIZE_BYTES = 1;
13 | const HEADER_SIZE_BYTES = LENGTH_FIELD_SIZE_BYTES + OP_FIELD_SIZE_BYTES;
14 |
15 | const intToBuffer = (i, length = 4) => {
16 | const buf = Buffer.alloc(length);
17 | if (length === 4) {
18 | buf.writeInt32BE(i, 0);
19 | } else if (length === 2) {
20 | buf.writeInt16BE(i, 0);
21 | } else if (length === 1) {
22 | buf.writeInt8(i, 0);
23 | } else {
24 | throw new Error('Illegal value specified for intToBuffer length. Must be 1, 2 or 4.');
25 | }
26 | return buf;
27 | };
28 |
29 | const intFromBuffer = (b) => {
30 | if (b.length >= 4) {
31 | return b.readInt32BE(0);
32 | } else {
33 | return b.readInt8(0);
34 | }
35 | };
36 |
37 | const encodeFrame = (frame) => {
38 | if (frame.payload.length + 1 > MAX_PACKET_SIZE) {
39 | throw new exceptions.RequestPayloadTooLargeException();
40 | }
41 |
42 | const buf = Buffer.alloc(HEADER_SIZE_BYTES);
43 | buf.writeInt32BE(frame.payload.length + 1, 0);
44 | buf.writeInt8(frame.operation.asMap(), LENGTH_FIELD_SIZE_BYTES);
45 | return { header: buf, payload: frame.payload };
46 | };
47 |
48 | /**
49 | * From https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
50 | * @ignore
51 | * @returns {string}
52 | */
53 | const uuidv4 = () => 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
54 | // eslint-disable-next-line no-bitwise
55 | const r = Math.random() * 16 | 0;
56 | const
57 | // eslint-disable-next-line no-bitwise,no-mixed-operators
58 | v = c === 'x' ? r : (r & 0x3 | 0x8);
59 | return v.toString(16);
60 | });
61 |
62 | const isInvalid = (o) => {
63 | if (o === null || typeof o === 'undefined') {
64 | return false;
65 | }
66 | if (!Object.prototype.hasOwnProperty.call(Object.getPrototypeOf(o).constructor, 'validationsMap')) {
67 | return false;
68 | }
69 |
70 | for (const [propName, validations] of Object.entries(Object.getPrototypeOf(o).constructor.validationsMap)) {
71 | if (!(propName in o)) {
72 | return `Object is malformed, missing property: ${propName}`;
73 | }
74 |
75 | // Validate all properties on arrays
76 | if (o[propName] instanceof Array) {
77 | for (const [i, v] of o[propName].entries()) {
78 | const result = isInvalid(v);
79 | if (result) {
80 | return `Property ${propName}[${i}] is invalid because ${result}`;
81 | }
82 | }
83 | }
84 |
85 | // Validate the property
86 | if ('required' in validations && validations.required && o[propName] === null) {
87 | return `Property ${propName} is required, but was null`;
88 | }
89 | if (
90 | 'minLength' in validations
91 | && o[propName] !== null
92 | && o[propName].length < validations.minLength
93 | ) {
94 | return `Property ${propName} must have a minimum length of ${validations.minLength}, but found length of ${o[propName].length}`;
95 | }
96 | if (
97 | 'maxLength' in validations
98 | && o[propName] !== null
99 | && o[propName].length > validations.maxLength
100 | ) {
101 | return `Property ${propName} must have a maximum length of ${validations.maxLength}, but found length of ${o[propName].length}`;
102 | }
103 | if (
104 | 'minItems' in validations
105 | && o[propName] !== null
106 | && o[propName].length < validations.minItems
107 | ) {
108 | return `Property ${propName} must have at least ${validations.minItems} items, but found ${o[propName].length}`;
109 | }
110 | if (
111 | 'maxItems' in validations
112 | && o[propName] !== null
113 | && o[propName].length > validations.maxItems
114 | ) {
115 | return `Property ${propName} must have at most ${validations.maxItems} items, but found ${o[propName].length}`;
116 | }
117 | if (
118 | 'maximum' in validations
119 | && o[propName] !== null
120 | && o[propName] > validations.maximum
121 | ) {
122 | return `Property ${propName} must be at most ${validations.maximum}`;
123 | }
124 | if (
125 | 'minimum' in validations
126 | && o[propName] !== null
127 | && o[propName] < validations.minimum
128 | ) {
129 | return `Property ${propName} must be at least ${validations.minimum}`;
130 | }
131 | if (
132 | 'pattern' in validations
133 | && o[propName] !== null
134 | && o[propName].match(validations.pattern) === null
135 | ) {
136 | return `Property ${propName} must match regex ${validations.pattern}`;
137 | }
138 | }
139 |
140 | // Recurse down to check validity of objects within objects
141 | for (const propName of Object.keys(Object.getPrototypeOf(o).constructor.validationsMap)) {
142 | const result = isInvalid(o[propName]);
143 | if (result) {
144 | return `Property ${propName} is invalid because ${result}`;
145 | }
146 | }
147 |
148 | return false;
149 | };
150 |
151 | const removeEmptyArray = (nam, val) => {
152 | if (val && val.length === 0) {
153 | return undefined; // remove from result
154 | } else {
155 | return val; // return as is
156 | }
157 | };
158 |
159 | const serializeToJsonWithEmptyArrayAsNull = (o) => Buffer.from(JSON.stringify(o, removeEmptyArray));
160 |
161 | const throwOnErrorResponse = (response) => {
162 | // eslint-disable-next-line no-empty
163 | if (response.status === smData.ResponseStatusCode.Success) {
164 |
165 | } else if (response.status === smData.ResponseStatusCode.InvalidRequest) {
166 | throw new exceptions.InvalidRequestException(response.errorMessage, response.status, response.requestId);
167 | } else if (response.status === smData.ResponseStatusCode.RequestPayloadTooLarge) {
168 | throw new exceptions.RequestPayloadTooLargeException(response.errorMessage, response.status, response.requestId);
169 | } else if (response.status === smData.ResponseStatusCode.ResourceNotFound) {
170 | throw new exceptions.ResourceNotFoundException(response.errorMessage, response.status, response.requestId);
171 | } else if (response.status === smData.ResponseStatusCode.ResponsePayloadTooLarge) {
172 | throw new exceptions.ResponsePayloadTooLargeException(response.errorMessage, response.status, response.requestId);
173 | } else if (response.status === smData.ResponseStatusCode.ServerTimeout) {
174 | throw new exceptions.ServerTimeoutException(response.errorMessage, response.status, response.requestId);
175 | } else if (response.status === smData.ResponseStatusCode.Unauthorized) {
176 | throw new exceptions.UnauthorizedException(response.errorMessage, response.status, response.requestId);
177 | } else if (response.status === smData.ResponseStatusCode.UnknownFailure) {
178 | throw new exceptions.UnknownFailureException(response.errorMessage, response.status, response.requestId);
179 | } else if (response.status === smData.ResponseStatusCode.NotEnoughMessages) {
180 | throw new exceptions.NotEnoughMessagesException(response.errorMessage, response.status, response.requestId);
181 | } else if (response.status === smData.ResponseStatusCode.MessageStoreReadError) {
182 | throw new exceptions.MessageStoreReadErrorException(response.errorMessage, response.status, response.requestId);
183 | } else if (response.status === smData.ResponseStatusCode.OutOfMemoryError) {
184 | throw new exceptions.ServerOutOfMemoryException(response.errorMessage, response.status, response.requestId);
185 | } else if (response.status === smData.ResponseStatusCode.UpdateFailed) {
186 | throw new exceptions.UpdateFailedException(response.errorMessage, response.status, response.requestId);
187 | } else if (response.status === smData.ResponseStatusCode.UpdateNotAllowed) {
188 | throw new exceptions.UpdateNotAllowedException(response.errorMessage, response.status, response.requestId);
189 | } else if (response.status === smData.ResponseStatusCode.UnknownOperation) {
190 | throw new exceptions.UnknownOperationException(response.errorMessage, response.status, response.requestId);
191 | } else {
192 | throw new exceptions.StreamManagerException(
193 | 'Client is not able to understand this server response status code', 'Unrecognized', response.requestId,
194 | );
195 | }
196 | };
197 |
198 | module.exports = {
199 | intToBuffer,
200 | intFromBuffer,
201 | encodeFrame,
202 | uuidv4,
203 | isInvalid,
204 | throwOnErrorResponse,
205 | serializeToJsonWithEmptyArrayAsNull,
206 | MAX_PACKET_SIZE,
207 | };
208 |
--------------------------------------------------------------------------------
/aws-greengrass-core-sdk/util.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
6 | const qualifierRegex = /(|[a-zA-Z0-9$_-]+)/;
7 |
8 | exports.getParameter = function _getParameter(params, desiredParam) {
9 | if (!Object.prototype.hasOwnProperty.call(params, desiredParam)) {
10 | return;
11 | }
12 | return params[desiredParam];
13 | };
14 |
15 | exports.isValidJSON = function _isValidJSON(str) {
16 | try {
17 | JSON.parse(str);
18 | } catch (e) {
19 | return false;
20 | }
21 | return true;
22 | };
23 |
24 | exports.isValidContext = function _isValidContext(context) {
25 | if (!base64Regex.test(context)) {
26 | return false;
27 | }
28 | try {
29 | JSON.stringify(context);
30 | } catch (e) {
31 | return false;
32 | }
33 | return true;
34 | };
35 |
36 | exports.isValidQualifier = function _isValidQualifier(qualifier) {
37 | if (!qualifierRegex.test(qualifier)) {
38 | return false;
39 | }
40 | return true;
41 | };
42 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws/aws-greengrass-core-sdk-js/2fd1c645d829ed63b30fbb667d337f890e4f4c3a/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/aws-greengrass-core-sdk.StreamManager.EventType.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | JSDoc: Class: EventType
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
ExportFormat is used to define how messages are batched and formatted in the export payload.
35 | RAW_NOT_BATCHED: Each message in a batch will be sent as an individual HTTP POST with the payload as the body (even if batchSize is set).
36 | JSON_BATCHED: Each batch of messages will be sent as a JSON list of Message objects as the body.
Stream persistence. If set to File, the file system will be used to persist messages long-term and is resilient to restarts.
35 | Memory should be used when performance matters more than durability as it only stores the stream in memory and never writes to the disk.
StrategyOnFull is used in the MessageStreamDefinition when creating a stream.
35 | It defines the behavior when the stream has reached the maximum size.
36 | RejectNewData: any append message request after the stream is full will be rejected with an exception.
37 | OverwriteOldestData: the oldest stream segments will be deleted until there is room for the new message.
70 |
71 |
74 |
75 |
76 |
77 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/docs/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | /*global document */
2 | (() => {
3 | const source = document.getElementsByClassName('prettyprint source linenums');
4 | let i = 0;
5 | let lineNumber = 0;
6 | let lineId;
7 | let lines;
8 | let totalLines;
9 | let anchorHash;
10 |
11 | if (source && source[0]) {
12 | anchorHash = document.location.hash.substring(1);
13 | lines = source[0].getElementsByTagName('li');
14 | totalLines = lines.length;
15 |
16 | for (; i < totalLines; i++) {
17 | lineNumber++;
18 | lineId = `line${lineNumber}`;
19 | lines[i].id = lineId;
20 | if (lineId === anchorHash) {
21 | lines[i].className += ' selected';
22 | }
23 | }
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/docs/scripts/prettify/Apache-License-2.0.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/docs/scripts/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/docs/stream-manager_index.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | JSDoc: Source: stream-manager/index.js
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Source: stream-manager/index.js
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
/*
30 | * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
31 | */
32 |
33 | /**
34 | * @namespace aws-greengrass-core-sdk.StreamManager
35 | */
36 |
37 | module.exports = require('./client');
38 |
/* eslint-disable no-restricted-syntax */
30 | /*
31 | * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
32 | */
33 |
34 | const exceptions = require('./exceptions');
35 | const utilInternal = require('./utilInternal');
36 |
37 | /**
38 | * Validate And Serialize an instance of class to Json bytes
39 | * @param o a instance object
40 | * @return byte array
41 | * @exception throws ValidationException
42 | */
43 | const validateAndSerializeToJsonBytes = (o) => {
44 | const validation = utilInternal.isInvalid(o);
45 | if (validation) {
46 | throw new exceptions.ValidationException(validation);
47 | }
48 | return utilInternal.serializeToJsonWithEmptyArrayAsNull(o.asMap());
49 | };
50 |
51 |
52 | /**
53 | * Deserialize the json byte array to an instance of class
54 | * @param bytes a bytes array
55 | * @param type instance type
56 | * @return object
57 | */
58 | const deserializeJsonBytesToObj = (bytes, type) => type.fromMap(JSON.parse(bytes.toString('utf-8')));
59 |
60 | module.exports = {
61 | validateAndSerializeToJsonBytes,
62 | deserializeJsonBytesToObj,
63 | };
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
76 |
77 |
78 |
79 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/docs/styles/jsdoc-default.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Open Sans';
3 | font-weight: normal;
4 | font-style: normal;
5 | src: url('../fonts/OpenSans-Regular-webfont.eot');
6 | src:
7 | local('Open Sans'),
8 | local('OpenSans'),
9 | url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
10 | url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
11 | url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg');
12 | }
13 |
14 | @font-face {
15 | font-family: 'Open Sans Light';
16 | font-weight: normal;
17 | font-style: normal;
18 | src: url('../fonts/OpenSans-Light-webfont.eot');
19 | src:
20 | local('Open Sans Light'),
21 | local('OpenSans Light'),
22 | url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
23 | url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
24 | url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg');
25 | }
26 |
27 | html
28 | {
29 | overflow: auto;
30 | background-color: #fff;
31 | font-size: 14px;
32 | }
33 |
34 | body
35 | {
36 | font-family: 'Open Sans', sans-serif;
37 | line-height: 1.5;
38 | color: #4d4e53;
39 | background-color: white;
40 | }
41 |
42 | a, a:visited, a:active {
43 | color: #0095dd;
44 | text-decoration: none;
45 | }
46 |
47 | a:hover {
48 | text-decoration: underline;
49 | }
50 |
51 | header
52 | {
53 | display: block;
54 | padding: 0px 4px;
55 | }
56 |
57 | tt, code, kbd, samp {
58 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
59 | }
60 |
61 | .class-description {
62 | font-size: 130%;
63 | line-height: 140%;
64 | margin-bottom: 1em;
65 | margin-top: 1em;
66 | }
67 |
68 | .class-description:empty {
69 | margin: 0;
70 | }
71 |
72 | #main {
73 | float: left;
74 | width: 70%;
75 | }
76 |
77 | article dl {
78 | margin-bottom: 40px;
79 | }
80 |
81 | article img {
82 | max-width: 100%;
83 | }
84 |
85 | section
86 | {
87 | display: block;
88 | background-color: #fff;
89 | padding: 12px 24px;
90 | border-bottom: 1px solid #ccc;
91 | margin-right: 30px;
92 | }
93 |
94 | .variation {
95 | display: none;
96 | }
97 |
98 | .signature-attributes {
99 | font-size: 60%;
100 | color: #aaa;
101 | font-style: italic;
102 | font-weight: lighter;
103 | }
104 |
105 | nav
106 | {
107 | display: block;
108 | float: right;
109 | margin-top: 28px;
110 | width: 30%;
111 | box-sizing: border-box;
112 | border-left: 1px solid #ccc;
113 | padding-left: 16px;
114 | }
115 |
116 | nav ul {
117 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
118 | font-size: 100%;
119 | line-height: 17px;
120 | padding: 0;
121 | margin: 0;
122 | list-style-type: none;
123 | }
124 |
125 | nav ul a, nav ul a:visited, nav ul a:active {
126 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
127 | line-height: 18px;
128 | color: #4D4E53;
129 | }
130 |
131 | nav h3 {
132 | margin-top: 12px;
133 | }
134 |
135 | nav li {
136 | margin-top: 6px;
137 | }
138 |
139 | footer {
140 | display: block;
141 | padding: 6px;
142 | margin-top: 12px;
143 | font-style: italic;
144 | font-size: 90%;
145 | }
146 |
147 | h1, h2, h3, h4 {
148 | font-weight: 200;
149 | margin: 0;
150 | }
151 |
152 | h1
153 | {
154 | font-family: 'Open Sans Light', sans-serif;
155 | font-size: 48px;
156 | letter-spacing: -2px;
157 | margin: 12px 24px 20px;
158 | }
159 |
160 | h2, h3.subsection-title
161 | {
162 | font-size: 30px;
163 | font-weight: 700;
164 | letter-spacing: -1px;
165 | margin-bottom: 12px;
166 | }
167 |
168 | h3
169 | {
170 | font-size: 24px;
171 | letter-spacing: -0.5px;
172 | margin-bottom: 12px;
173 | }
174 |
175 | h4
176 | {
177 | font-size: 18px;
178 | letter-spacing: -0.33px;
179 | margin-bottom: 12px;
180 | color: #4d4e53;
181 | }
182 |
183 | h5, .container-overview .subsection-title
184 | {
185 | font-size: 120%;
186 | font-weight: bold;
187 | letter-spacing: -0.01em;
188 | margin: 8px 0 3px 0;
189 | }
190 |
191 | h6
192 | {
193 | font-size: 100%;
194 | letter-spacing: -0.01em;
195 | margin: 6px 0 3px 0;
196 | font-style: italic;
197 | }
198 |
199 | table
200 | {
201 | border-spacing: 0;
202 | border: 0;
203 | border-collapse: collapse;
204 | }
205 |
206 | td, th
207 | {
208 | border: 1px solid #ddd;
209 | margin: 0px;
210 | text-align: left;
211 | vertical-align: top;
212 | padding: 4px 6px;
213 | display: table-cell;
214 | }
215 |
216 | thead tr
217 | {
218 | background-color: #ddd;
219 | font-weight: bold;
220 | }
221 |
222 | th { border-right: 1px solid #aaa; }
223 | tr > th:last-child { border-right: 1px solid #ddd; }
224 |
225 | .ancestors, .attribs { color: #999; }
226 | .ancestors a, .attribs a
227 | {
228 | color: #999 !important;
229 | text-decoration: none;
230 | }
231 |
232 | .clear
233 | {
234 | clear: both;
235 | }
236 |
237 | .important
238 | {
239 | font-weight: bold;
240 | color: #950B02;
241 | }
242 |
243 | .yes-def {
244 | text-indent: -1000px;
245 | }
246 |
247 | .type-signature {
248 | color: #aaa;
249 | }
250 |
251 | .name, .signature {
252 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
253 | }
254 |
255 | .details { margin-top: 14px; border-left: 2px solid #DDD; }
256 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; }
257 | .details dd { margin-left: 70px; }
258 | .details ul { margin: 0; }
259 | .details ul { list-style-type: none; }
260 | .details li { margin-left: 30px; padding-top: 6px; }
261 | .details pre.prettyprint { margin: 0 }
262 | .details .object-value { padding-top: 0; }
263 |
264 | .description {
265 | margin-bottom: 1em;
266 | margin-top: 1em;
267 | }
268 |
269 | .code-caption
270 | {
271 | font-style: italic;
272 | font-size: 107%;
273 | margin: 0;
274 | }
275 |
276 | .source
277 | {
278 | border: 1px solid #ddd;
279 | width: 80%;
280 | overflow: auto;
281 | }
282 |
283 | .prettyprint.source {
284 | width: inherit;
285 | }
286 |
287 | .source code
288 | {
289 | font-size: 100%;
290 | line-height: 18px;
291 | display: block;
292 | padding: 4px 12px;
293 | margin: 0;
294 | background-color: #fff;
295 | color: #4D4E53;
296 | }
297 |
298 | .prettyprint code span.line
299 | {
300 | display: inline-block;
301 | }
302 |
303 | .prettyprint.linenums
304 | {
305 | padding-left: 70px;
306 | -webkit-user-select: none;
307 | -moz-user-select: none;
308 | -ms-user-select: none;
309 | user-select: none;
310 | }
311 |
312 | .prettyprint.linenums ol
313 | {
314 | padding-left: 0;
315 | }
316 |
317 | .prettyprint.linenums li
318 | {
319 | border-left: 3px #ddd solid;
320 | }
321 |
322 | .prettyprint.linenums li.selected,
323 | .prettyprint.linenums li.selected *
324 | {
325 | background-color: lightyellow;
326 | }
327 |
328 | .prettyprint.linenums li *
329 | {
330 | -webkit-user-select: text;
331 | -moz-user-select: text;
332 | -ms-user-select: text;
333 | user-select: text;
334 | }
335 |
336 | .params .name, .props .name, .name code {
337 | color: #4D4E53;
338 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
339 | font-size: 100%;
340 | }
341 |
342 | .params td.description > p:first-child,
343 | .props td.description > p:first-child
344 | {
345 | margin-top: 0;
346 | padding-top: 0;
347 | }
348 |
349 | .params td.description > p:last-child,
350 | .props td.description > p:last-child
351 | {
352 | margin-bottom: 0;
353 | padding-bottom: 0;
354 | }
355 |
356 | .disabled {
357 | color: #454545;
358 | }
359 |
--------------------------------------------------------------------------------
/docs/styles/prettify-jsdoc.css:
--------------------------------------------------------------------------------
1 | /* JSDoc prettify.js theme */
2 |
3 | /* plain text */
4 | .pln {
5 | color: #000000;
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | /* string content */
11 | .str {
12 | color: #006400;
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
17 | /* a keyword */
18 | .kwd {
19 | color: #000000;
20 | font-weight: bold;
21 | font-style: normal;
22 | }
23 |
24 | /* a comment */
25 | .com {
26 | font-weight: normal;
27 | font-style: italic;
28 | }
29 |
30 | /* a type name */
31 | .typ {
32 | color: #000000;
33 | font-weight: normal;
34 | font-style: normal;
35 | }
36 |
37 | /* a literal value */
38 | .lit {
39 | color: #006400;
40 | font-weight: normal;
41 | font-style: normal;
42 | }
43 |
44 | /* punctuation */
45 | .pun {
46 | color: #000000;
47 | font-weight: bold;
48 | font-style: normal;
49 | }
50 |
51 | /* lisp open bracket */
52 | .opn {
53 | color: #000000;
54 | font-weight: bold;
55 | font-style: normal;
56 | }
57 |
58 | /* lisp close bracket */
59 | .clo {
60 | color: #000000;
61 | font-weight: bold;
62 | font-style: normal;
63 | }
64 |
65 | /* a markup tag name */
66 | .tag {
67 | color: #006400;
68 | font-weight: normal;
69 | font-style: normal;
70 | }
71 |
72 | /* a markup attribute name */
73 | .atn {
74 | color: #006400;
75 | font-weight: normal;
76 | font-style: normal;
77 | }
78 |
79 | /* a markup attribute value */
80 | .atv {
81 | color: #006400;
82 | font-weight: normal;
83 | font-style: normal;
84 | }
85 |
86 | /* a declaration */
87 | .dec {
88 | color: #000000;
89 | font-weight: bold;
90 | font-style: normal;
91 | }
92 |
93 | /* a variable name */
94 | .var {
95 | color: #000000;
96 | font-weight: normal;
97 | font-style: normal;
98 | }
99 |
100 | /* a function name */
101 | .fun {
102 | color: #000000;
103 | font-weight: bold;
104 | font-style: normal;
105 | }
106 |
107 | /* Specify class=linenums on a pre to get line numbering */
108 | ol.linenums {
109 | margin-top: 0;
110 | margin-bottom: 0;
111 | }
112 |
--------------------------------------------------------------------------------
/docs/styles/prettify-tomorrow.css:
--------------------------------------------------------------------------------
1 | /* Tomorrow Theme */
2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */
3 | /* Pretty printing styles. Used with prettify.js. */
4 | /* SPAN elements with the classes below are added by prettyprint. */
5 | /* plain text */
6 | .pln {
7 | color: #4d4d4c; }
8 |
9 | @media screen {
10 | /* string content */
11 | .str {
12 | color: #718c00; }
13 |
14 | /* a keyword */
15 | .kwd {
16 | color: #8959a8; }
17 |
18 | /* a comment */
19 | .com {
20 | color: #8e908c; }
21 |
22 | /* a type name */
23 | .typ {
24 | color: #4271ae; }
25 |
26 | /* a literal value */
27 | .lit {
28 | color: #f5871f; }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #4d4d4c; }
33 |
34 | /* lisp open bracket */
35 | .opn {
36 | color: #4d4d4c; }
37 |
38 | /* lisp close bracket */
39 | .clo {
40 | color: #4d4d4c; }
41 |
42 | /* a markup tag name */
43 | .tag {
44 | color: #c82829; }
45 |
46 | /* a markup attribute name */
47 | .atn {
48 | color: #f5871f; }
49 |
50 | /* a markup attribute value */
51 | .atv {
52 | color: #3e999f; }
53 |
54 | /* a declaration */
55 | .dec {
56 | color: #f5871f; }
57 |
58 | /* a variable name */
59 | .var {
60 | color: #c82829; }
61 |
62 | /* a function name */
63 | .fun {
64 | color: #4271ae; } }
65 | /* Use higher contrast and text-weight for printable form. */
66 | @media print, projection {
67 | .str {
68 | color: #060; }
69 |
70 | .kwd {
71 | color: #006;
72 | font-weight: bold; }
73 |
74 | .com {
75 | color: #600;
76 | font-style: italic; }
77 |
78 | .typ {
79 | color: #404;
80 | font-weight: bold; }
81 |
82 | .lit {
83 | color: #044; }
84 |
85 | .pun, .opn, .clo {
86 | color: #440; }
87 |
88 | .tag {
89 | color: #006;
90 | font-weight: bold; }
91 |
92 | .atn {
93 | color: #404; }
94 |
95 | .atv {
96 | color: #060; } }
97 | /* Style */
98 | /*
99 | pre.prettyprint {
100 | background: white;
101 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
102 | font-size: 12px;
103 | line-height: 1.5;
104 | border: 1px solid #ccc;
105 | padding: 10px; }
106 | */
107 |
108 | /* Specify class=linenums on a pre to get line numbering */
109 | ol.linenums {
110 | margin-top: 0;
111 | margin-bottom: 0; }
112 |
113 | /* IE indents via margin-left */
114 | li.L0,
115 | li.L1,
116 | li.L2,
117 | li.L3,
118 | li.L4,
119 | li.L5,
120 | li.L6,
121 | li.L7,
122 | li.L8,
123 | li.L9 {
124 | /* */ }
125 |
126 | /* Alternate shading for lines */
127 | li.L1,
128 | li.L3,
129 | li.L5,
130 | li.L7,
131 | li.L9 {
132 | /* */ }
133 |
--------------------------------------------------------------------------------
/greengrassExamples/HelloWorld/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * Demonstrates a simple publish to a topic using Greengrass Core NodeJS SDK
7 | * This lambda function will retrieve underlying platform information and send
8 | * a hello world message along with the platform information to the topic
9 | * 'hello/world'. The function will sleep for five seconds, then repeat.
10 | * Since the function is long-lived it will run forever when deployed to a
11 | * Greengrass core.
12 | */
13 |
14 | const ggSdk = require('aws-greengrass-core-sdk');
15 |
16 | const iotClient = new ggSdk.IotData();
17 | const os = require('os');
18 | const util = require('util');
19 |
20 | function publishCallback(err, data) {
21 | console.log(err);
22 | console.log(data);
23 | }
24 |
25 | const myPlatform = util.format('%s-%s', os.platform(), os.release());
26 | const pubOpt = {
27 | topic: 'hello/world',
28 | payload: JSON.stringify({ message: util.format('Hello world! Sent from Greengrass Core running on platform: %s using NodeJS', myPlatform) }),
29 | queueFullPolicy: 'AllOrError',
30 | };
31 |
32 | function greengrassHelloWorldRun() {
33 | iotClient.publish(pubOpt, publishCallback);
34 | }
35 |
36 | // Schedule the job to run every 5 seconds
37 | setInterval(greengrassHelloWorldRun, 5000);
38 |
39 | // This is a handler which does nothing for this example
40 | exports.handler = function handler(event, context) {
41 | console.log(event);
42 | console.log(context);
43 | };
44 |
--------------------------------------------------------------------------------
/greengrassExamples/LambdaInvoke/invokee.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * Demonstrates how to return a result back to the caller of this lambda
7 | */
8 |
9 | exports.handler = function handler(event, context, callback) {
10 | console.log(event);
11 | console.log(context);
12 | callback(undefined, { result: 'message' });
13 | };
14 |
--------------------------------------------------------------------------------
/greengrassExamples/LambdaInvoke/invokerbinary.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * Demonstrates how to invoke another lambda with binary data and receive the value from the call
7 | */
8 |
9 | const ggSdk = require('aws-greengrass-core-sdk');
10 |
11 | const lambdaClient = new ggSdk.Lambda();
12 |
13 | exports.handler = function handler(event, context) {
14 | console.log(event);
15 | console.log(context);
16 |
17 | const cxt = {
18 | custom: {
19 | customData: 'customData',
20 | },
21 | };
22 | const contextString = JSON.stringify(cxt);
23 | const buff = Buffer.from(contextString);
24 | const clientContext = buff.toString('base64');
25 |
26 | const params = {
27 | FunctionName: 'arn::lambda:::function::',
28 | InvocationType: 'RequestResponse',
29 | ClientContext: clientContext,
30 | Payload: Buffer.from('payload message', 'utf8'),
31 | };
32 |
33 | lambdaClient.invoke(params, (err, data) => {
34 | if (err) {
35 | console.error(err, err.stack);
36 | } else {
37 | console.log(data);
38 | }
39 | });
40 | };
41 |
--------------------------------------------------------------------------------
/greengrassExamples/LambdaInvoke/invokerjson.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * Demonstrates how to invoke another lambda with json data and receive the value from the call
7 | */
8 |
9 | const ggSdk = require('aws-greengrass-core-sdk');
10 |
11 | const lambdaClient = new ggSdk.Lambda();
12 |
13 | exports.handler = function handler(event, context) {
14 | console.log(event);
15 | console.log(context);
16 |
17 | const cxt = {
18 | custom: {
19 | customData: 'customData',
20 | },
21 | };
22 | const contextString = JSON.stringify(cxt);
23 | const buff = Buffer.from(contextString);
24 | const clientContext = buff.toString('base64');
25 |
26 | const params = {
27 | FunctionName: 'arn::lambda:::function::',
28 | InvocationType: 'RequestResponse',
29 | ClientContext: clientContext,
30 | Payload: JSON.stringify({ message: 'payload message' }),
31 | };
32 |
33 | lambdaClient.invoke(params, (err, data) => {
34 | if (err) {
35 | console.error(err, err.stack);
36 | } else {
37 | console.log(data);
38 | }
39 | });
40 | };
41 |
--------------------------------------------------------------------------------
/greengrassExamples/ShadowOperations/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * Demonstrates a shadow operation using Greengrass Core NodeJS SDK
7 | * This lambda function will retrieve underlying platform information and
8 | * update the reported state of 'platform' shadow with that message.
9 | */
10 |
11 | const ggSdk = require('aws-greengrass-core-sdk');
12 |
13 | const iotClient = new ggSdk.IotData();
14 | const os = require('os');
15 | const util = require('util');
16 |
17 | const myPlatform = util.format('%s-%s', os.platform(), os.release());
18 | const shadowUpdateParams = {
19 | thingName: 'platform',
20 | payload: JSON.stringify({ state: { reported: { platform: myPlatform } } }),
21 | };
22 | const shadowGetParams = {
23 | thingName: 'platform',
24 | };
25 |
26 | exports.handler = function handler(event, context) {
27 | console.log(context);
28 |
29 | // Update Thing Shadow
30 | console.log('Update Thing Operation');
31 | iotClient.updateThingShadow(shadowUpdateParams, (err, data) => {
32 | if (err) {
33 | console.log(err);
34 | } else {
35 | console.log(data);
36 | }
37 | });
38 |
39 | // Get Thing Shadow
40 | console.log('Shadow Get Operation');
41 | iotClient.getThingShadow(shadowGetParams, (err, data) => {
42 | if (err) {
43 | console.log(err);
44 | } else {
45 | console.log(data);
46 | }
47 | });
48 | };
49 |
--------------------------------------------------------------------------------
/greengrassExamples/StreamManagerIoTSiteWise/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * This example will create a Greengrass StreamManager stream called "SomeStream".
7 | * It will then start writing data into that stream and StreamManager will
8 | * automatically export the written data to the customer-created property alias.
9 | * The property alias should be created before running this example.
10 | * This example will run forever, until the program is killed.
11 |
12 | * The size of the StreamManager stream on disk will not exceed the default (which is 256 MB).
13 | * Any data appended after the stream reaches the size limit, will continue to be appended, and
14 | * StreamManager will delete the oldest data until the total stream size is back under 256MB.
15 | */
16 |
17 | const {
18 | StreamManagerClient, ExportDefinition,
19 | IoTSiteWiseConfig, MessageStreamDefinition, StrategyOnFull,
20 | ResourceNotFoundException, AssetPropertyValue, PutAssetPropertyValueEntry, Quality, TimeInNanos, Variant,
21 | util,
22 | } = require('aws-greengrass-core-sdk').StreamManager;
23 |
24 | const STREAM_NAME = 'SomeStream';
25 | const PROPERTY_ALIAS = 'SomePropertyAlias';
26 | const ENTRY_ID_PREFIX = 'SomeEntryId-';
27 |
28 | const c = new StreamManagerClient();
29 |
30 | function getRandomPutAssetPropertyValueEntry(i) {
31 | const maxTimeRandomness = 60;
32 | const maxOffsetRandomness = 10000;
33 | const randomValue = Math.random();
34 | // Note: Inorder to create a new asset property data, you should use the classes defined in the
35 | // aws-greengrass-core-sdk StreamManager module.
36 | const timestamp = new TimeInNanos()
37 | .withTimeInSeconds(Math.round(Date.now() / 1000) - Math.floor(Math.random() - maxTimeRandomness))
38 | .withOffsetInNanos(Math.floor(Math.random() * maxOffsetRandomness));
39 | const entry = new AssetPropertyValue()
40 | .withValue(new Variant().withDoubleValue(randomValue))
41 | .withQuality(Quality.GOOD)
42 | .withTimestamp(timestamp);
43 |
44 | return new PutAssetPropertyValueEntry()
45 | .withEntryId(`${ENTRY_ID_PREFIX}${i}`)
46 | .withPropertyAlias(PROPERTY_ALIAS)
47 | .withPropertyValues([entry]);
48 | }
49 |
50 | c.onConnected(async () => {
51 | // Try deleting the stream (if it exists) so that we have a fresh start
52 | try {
53 | await c.deleteMessageStream(STREAM_NAME);
54 | } catch (e) {
55 | // Rethrow the error if it wasn't the expected error
56 | if (!(e instanceof ResourceNotFoundException)) {
57 | throw e;
58 | }
59 | }
60 |
61 | try {
62 | const exports = new ExportDefinition()
63 | .withIotSitewise([new IoTSiteWiseConfig()
64 | .withIdentifier(`IoTSiteWise-${STREAM_NAME}`)
65 | .withBatchSize(5)]);
66 |
67 | // Then create the stream with the IoTSiteWise export definition.
68 | await c.createMessageStream(
69 | new MessageStreamDefinition()
70 | .withName(STREAM_NAME)
71 | .withStrategyOnFull(StrategyOnFull.OverwriteOldestData)
72 | .withExportDefinition(exports),
73 | );
74 |
75 | let index = 0;
76 | // Now start putting in random SiteWise entries.
77 | const interval = setInterval(async () => {
78 | try {
79 | console.log('Appending new random SiteWise entries to stream');
80 | await c.appendMessage(STREAM_NAME, util.validateAndSerializeToJsonBytes(getRandomPutAssetPropertyValueEntry(index++)));
81 | } catch {
82 | clearInterval(interval);
83 | c.close();
84 | }
85 | }, 1000);
86 | } catch (e) {
87 | console.log(e);
88 | c.close();
89 | }
90 | });
91 |
92 | // Dummy handler because this example should run as a long-lived lambda
93 | module.exports.handler = function handler() {
94 | return '';
95 | };
96 |
--------------------------------------------------------------------------------
/greengrassExamples/StreamManagerKinesis/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * This example will create a Greengrass StreamManager stream called "SomeStream".
7 | * It will then start writing data into that stream and StreamManager will
8 | * automatically export the written data to a Kinesis Data Stream called "MyKinesisStream".
9 | * This example will run forever, until the program is killed.
10 | *
11 | * The size of the StreamManager stream on disk will not exceed the default (which is 256 MB).
12 | * Any data appended after the stream reaches the size limit, will continue to be appended, and
13 | * StreamManager will delete the oldest data until the total stream size is back under 256MB.
14 | * The Kinesis Data Stream in the cloud has no such bound, so all the data from this script
15 | * will be uploaded to Kinesis and you will be charged for that usage.
16 | */
17 |
18 | const {
19 | StreamManagerClient, ReadMessagesOptions, ExportDefinition,
20 | KinesisConfig, MessageStreamDefinition, StrategyOnFull,
21 | ResourceNotFoundException,
22 | } = require('aws-greengrass-core-sdk').StreamManager;
23 |
24 | const STREAM_NAME = 'SomeStream';
25 | const KINESIS_STREAM_NAME = 'MyKinesisStream';
26 |
27 | const c = new StreamManagerClient();
28 | c.onConnected(async () => {
29 | // Try deleting the stream (if it exists) so that we have a fresh start
30 | try {
31 | await c.deleteMessageStream(STREAM_NAME);
32 | } catch (e) {
33 | // Rethrow the error if it wasn't the expected error
34 | if (!(e instanceof ResourceNotFoundException)) {
35 | throw e;
36 | }
37 | }
38 |
39 | try {
40 | const exports = new ExportDefinition()
41 | .withKinesis([new KinesisConfig()
42 | .withIdentifier(`KinesisExport${STREAM_NAME}`)
43 | .withKinesisStreamName(KINESIS_STREAM_NAME)]);
44 |
45 | await c.createMessageStream(
46 | new MessageStreamDefinition()
47 | .withName(STREAM_NAME)
48 | .withStrategyOnFull(StrategyOnFull.OverwriteOldestData)
49 | .withExportDefinition(exports),
50 | );
51 |
52 | // Append 2 messages and print their sequence numbers
53 | console.log(`Successfully appended message to stream with sequence number ${await c.appendMessage(STREAM_NAME, Buffer.from('ABCDEFGHIJKLMNO', 'utf-8'))}`);
54 | console.log(`Successfully appended message to stream with sequence number ${await c.appendMessage(STREAM_NAME, Buffer.from('PQRSTUVWXYZ', 'utf-8'))}`);
55 |
56 | // Try reading the 2 messages we just appended and print them out
57 | console.log(`Successfully read 2 messages: ${
58 | await c.readMessages(STREAM_NAME,
59 | new ReadMessagesOptions()
60 | .withMinMessageCount(2)
61 | .withReadTimeoutMillis(1000))}`);
62 |
63 | console.log('Now going to start writing random integers between 0 and 255 to the stream');
64 |
65 | // Now start putting in random data between 0 and 255 to emulate device sensor input
66 | const interval = setInterval(async () => {
67 | try {
68 | console.log('Appending new random integer to stream');
69 | const buf = Buffer.alloc(1);
70 | buf.writeUInt8(Math.floor(Math.random() * 255), 0);
71 | await c.appendMessage(STREAM_NAME, buf);
72 | } catch {
73 | clearInterval(interval);
74 | c.close();
75 | }
76 | }, 1000);
77 | } catch {
78 | c.close();
79 | }
80 | });
81 |
82 | // Dummy handler because this example should run as a pinned lambda
83 | module.exports.handler = function handler() {
84 | return '';
85 | };
86 |
--------------------------------------------------------------------------------
/greengrassExamples/StreamManagerS3/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * This example creates a local stream named 'SomeStream', and a status stream named 'SomeStatusStream.
7 | * It adds 1 S3 Export task into the 'SomeStream' stream and then stream manager automatically exports
8 | * the data to a customer-created S3 bucket named 'SomeBucket'.
9 | * The S3 bucket should be created before running this example.
10 | * This example runs until the customer-created file at URL 'SomeURL' has been uploaded to the S3 bucket.
11 | */
12 |
13 | const {
14 | StreamManagerClient, ReadMessagesOptions, ExportDefinition,
15 | MessageStreamDefinition, StrategyOnFull, ResourceNotFoundException,
16 | S3ExportTaskDefinition, Status, StatusConfig, StatusLevel, StatusMessage, S3ExportTaskExecutorConfig,
17 | util,
18 | } = require('aws-greengrass-core-sdk').StreamManager;
19 |
20 | const STREAM_NAME = 'SomeStream';
21 | const STATUS_STREAM_NAME = 'SomeStatusStream';
22 | const BUCKET = 'SomeBucket';
23 | const KEY = 'SomeKey';
24 | const FILE_URL = 'file:/path/to/some/file.someExtension';
25 |
26 | const c = new StreamManagerClient();
27 | c.onConnected(async () => {
28 | // Try deleting the stream (if it exists) so that we have a fresh start
29 | try {
30 | await c.deleteMessageStream(STATUS_STREAM_NAME);
31 | } catch (e) {
32 | // Rethrow the error if it wasn't the expected error
33 | if (!(e instanceof ResourceNotFoundException)) {
34 | throw e;
35 | }
36 | }
37 | // Try deleting the stream (if it exists) so that we have a fresh start
38 | try {
39 | await c.deleteMessageStream(STREAM_NAME);
40 | } catch (e) {
41 | // Rethrow the error if it wasn't the expected error
42 | if (!(e instanceof ResourceNotFoundException)) {
43 | throw e;
44 | }
45 | }
46 |
47 | try {
48 | const exports = new ExportDefinition()
49 | .withS3TaskExecutor([new S3ExportTaskExecutorConfig()
50 | .withIdentifier(`S3Export-${STREAM_NAME}`)
51 | .withStatusConfig(new StatusConfig()
52 | .withStatusLevel(StatusLevel.INFO)
53 | .withStatusStreamName(STATUS_STREAM_NAME))]);
54 |
55 | // Create the export status stream first.
56 | await c.createMessageStream(
57 | new MessageStreamDefinition()
58 | .withName(STATUS_STREAM_NAME)
59 | .withStrategyOnFull(StrategyOnFull.OverwriteOldestData),
60 | );
61 |
62 | // Then create the stream with the S3 Export definition.
63 | await c.createMessageStream(
64 | new MessageStreamDefinition()
65 | .withName(STREAM_NAME)
66 | .withStrategyOnFull(StrategyOnFull.OverwriteOldestData)
67 | .withExportDefinition(exports),
68 | );
69 |
70 | // Append a S3 export task definition and print the sequence number.
71 | const taskDefinition = new S3ExportTaskDefinition()
72 | .withBucket(BUCKET)
73 | .withKey(KEY)
74 | .withInputUrl(FILE_URL);
75 |
76 | console.log(`Successfully appended message to stream with sequence number
77 | ${await c.appendMessage(STREAM_NAME, util.validateAndSerializeToJsonBytes(taskDefinition))}`);
78 |
79 | console.log('Now going to start reading statuses from the export status stream.');
80 | let isS3UploadComplete = false;
81 | while (!isS3UploadComplete) {
82 | try {
83 | // Read the statuses from the export status stream
84 | const messages = await c.readMessages(STATUS_STREAM_NAME,
85 | new ReadMessagesOptions()
86 | .withMinMessageCount(1)
87 | .withReadTimeoutMillis(1000));
88 |
89 | messages.forEach((message) => {
90 | // Deserialize the status message first.
91 | const statusMessage = util.deserializeJsonBytesToObj(message.payload, StatusMessage);
92 | // Check the status of the status message. If the status is 'Success', the file was successfully uploaded to S3.
93 | // If the status was either 'Failure' or 'Cancelled', the server was unable to upload the file to S3.
94 | // We will print the message for why the upload to S3 failed from the status message.
95 | // If the status was "InProgress", the status indicates that the server has started uploading the S3 task.
96 | if (statusMessage.status === Status.Success) {
97 | console.log(`Successfully uploaded file at path ${FILE_URL} to S3.`);
98 | isS3UploadComplete = true;
99 | } else if (statusMessage.status === Status.Failure || statusMessage.status === Status.Canceled) {
100 | console.log(`Unable to upload file at path ${FILE_URL} to S3. Message: ${statusMessage.message}`);
101 | isS3UploadComplete = true;
102 | }
103 | });
104 | // Sleep for sometime for the S3 upload task to complete before trying to read the status message.
105 | await new Promise((r) => setTimeout(r, 5000));
106 | } catch (e) {
107 | // Ignored
108 | }
109 | }
110 | } catch (e) {
111 | c.close();
112 | }
113 | });
114 |
115 | // Dummy handler because this example should run as a pinned lambda
116 | module.exports.handler = function handler() {
117 | return '';
118 | };
119 |
--------------------------------------------------------------------------------
/greengrassExamples/TES/README:
--------------------------------------------------------------------------------
1 | The TES example package contains a Lambda function that, when run,
2 | will attempt to retrieve AWS credentials. The goal of TES is to allow
3 | users to retrieve credentials without having them hard-coded on the
4 | system itself.
5 |
6 | Assuming no credentials exist on the system, when the Lambda function
7 | is run, temporary credentials will be sourced from the cloud.
8 |
9 | The credential retrieval is retrieved with an incremental backoff
10 | in case of an error. Users must be aware that the retrieval may not
11 | always succeed on the first try and retry should be performed with care.
12 |
13 | ### SETUP ###
14 | 1. Copy the included index.js to your Lambda function.
15 |
16 | 2. Install aws-sdk by performing "npm install aws-sdk".
17 |
18 | 3. Unzip the Greengrass Core SDK for NodeJS into node_modules folder.
19 |
20 | 4. Zip the folder with index.js on the top level.
21 |
22 | 5. Create a Lambda in the Lambda Console.
23 | Handler: index.handler
24 | Runtime: Node.js 8.10
25 | Timeout: 3s
26 | Role: any basic execution role can be used here
27 |
28 | 6. Create a group that contains your Greengrass Core and the Lambda
29 | function you've just created.
30 |
31 | 7. In the Greengrass console, click on the Lambda function and set
32 | the Memory limit is at least 40MB and "Lambda lifecycle" is set to
33 | "Make this function long-lived and keep it running indefinitely".
34 |
35 | 8. Under Settings page of the group, make sure the Group Role is
36 | set to the role you want to use within Greengrass when
37 | performing actions against AWS.
38 |
39 | 9. Deploy the latest Greengrass to your device.
40 |
41 | 10. Local log should display the access key, secret key and session token.
42 |
--------------------------------------------------------------------------------
/greengrassExamples/TES/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | */
4 |
5 | /*
6 | * Demonstrates retrieving a Group Role Credential if one is set.
7 | */
8 |
9 | const AWS = require('aws-sdk');
10 | const util = require('util');
11 |
12 | const credChain = new AWS.CredentialProviderChain();
13 |
14 | // Max retry every 30 seconds to retrieve the credentials
15 | const maxRetryInterval = 30;
16 | // Initially, try with one second retry interval
17 | const initialRetryInterval = 1;
18 |
19 | function getCredential(retryInterval) {
20 | const promise = credChain.resolvePromise();
21 |
22 | promise.then((creds) => {
23 | console.log(util.format('Access Key: %s\nSecret Key: %s\nSession Key: %s\n', creds.accessKeyId, creds.secretAccessKey, creds.sessionToken));
24 | },
25 | (err) => {
26 | console.log(err);
27 | // Try again with incremental backoff
28 | setTimeout(() => {
29 | getCredential(Math.min(maxRetryInterval, retryInterval * 2));
30 | }, retryInterval);
31 | });
32 | }
33 |
34 | getCredential(initialRetryInterval);
35 |
36 | // This is a handler which does nothing for this example
37 | exports.handler = function handler(event, context) {
38 | console.log(event);
39 | console.log(context);
40 | };
41 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## AWS Greengrass Core SDK for JavaScript
2 |
3 | The **AWS Greengrass Core SDK for JavaScript** allows developers to write JavaScript Lambda functions which will run within Greengrass.
4 |
5 | ## Overview
6 |
7 | This document provides instructions for preparing your Greengrass Core environment to run Lambda functions written in JavaScript. It also includes examples on how to develop a Lambda function in JavaScript as well as packaging and running an example Hello World file in JavaScript for your Greengrass core.
8 |
9 | ## Preparing your Greengrass to run NodeJS Lambda functions
10 |
11 | The environment where Greengrass is running on needs to be able to run NodeJS 12.x applications.
12 |
13 | * Install NodeJS 12 for your platform. You can download the newest NodeJS from [https://nodejs.org/en/download/](https://nodejs.org/en/download/).
14 | * When you untar the package downloaded from NodeJS website, you will find `node` file under `bin` directory.
15 | * Copy the file to _**/usr/bin**_ or _**/usr/local/bin**_ folder.
16 | * Rename the file to _**nodejs12.x**_
17 |
18 | ## Getting Started - Hello World
19 |
20 | * Copy `greengrassExamples/HelloWorld` folder to your workspace.
21 | * Create a folder `node_modules` under `HelloWorld` folder.
22 | * Unzip aws-greengrass-core-sdk-js.zip into the folder. It should create a folder HelloWorld/node_modules/aws-greengrass-core-sdk
23 | * Use NPM to install the required dependency, cbor. `npm i cbor@5.0.1`.
24 | * Zip up the content of HelloWorld folder so that the index.js is on the top of the zip file structure.
25 | * Go to AWS Lambda Console.
26 | * Create a new function.
27 | * Choose the Runtime as `Node.js 12.x`
28 | * Upload the zip file in _Lambda function code_ section.
29 | * Handler is _index.handler_
30 | * Choose any role as the role is not used within Greengrass.
31 | * After creating the function, publish the Lambda.
32 | * Create an Alias and point to the Published version (not $LATEST).
33 | * Go to your Greengrass Group and add the Lambda under Lambdas section.
34 | * Click on the Lambda and change the _Lambda lifecycle_ to _Make this function long-lived and keep it running indefinitely._
35 | * Add a Subscription with the following configuration:
36 | * Source: Lambda which you just created and added to the group
37 | * Target: IoT Cloud
38 | * Topic: hello/world
39 | * Deploy. A message from your Lambda should be published to the topic _hello/world_ in the cloud every 5 seconds. You can check this by going to AWS IoT's _Test_ page and subscribing to topic _hello/world_.
40 |
41 | ## Including aws-greengrass-core-sdk with your function
42 |
43 | Unzip the SDK into your node_modules folder of your function. This should create a aws-greengrass-core-sdk folder which includes the SDK.
44 |
45 | ## Logging in NodeJS Lambdas
46 |
47 | Your _console.log_ operation will be logged as INFO. A _console.error_ operation will be logged as ERROR. Currently, our NodeJS SDK only allows you to log at INFO or ERROR level only.
48 |
49 | ## Supported Datatypes
50 |
51 | From GGC version 1.5, you can send both JSON and binary data as a payload when you invoking other Lambdas or publishing a message using IotData service. In order to make your lambda be able to handle binary payload, you need to configure the lambda in Greengrass console to mark it using binary input payload so that GGC can know how to deal with the data.
52 |
53 | ## Supported Context
54 |
55 | In Greengrass, you can send a context object in a JSON format to be passed to another Lambda that is being invoked. The context format looks like this: `{ custom: { customData: 'customData', }, }`
56 |
57 |
58 |
59 | ## Compatibility[¶](#compatibility "Permalink to this headline")
60 |
61 | As new features are added to AWS IoT Greengrass, newer versions of the AWS IoT Greengrass SDK may be incompatible with older versions of the AWS IoT Greengrass core. The following table lists the compatible SDKs for all GGC releases.
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
GGC Version
71 |
72 |
Compatible SDK Versions
73 |
74 |
75 |
76 |
77 |
78 |
1.0.x-1.6.x
79 |
80 |
1.0.x-1.2.x
81 |
82 |
83 |
84 |
85 |
86 |
1.7.x-1.8.x
87 |
88 |
1.0.x-1.3.x
89 |
90 |
91 |
92 |
93 |
94 |
1.9.x
95 |
96 |
1.0.x-1.4.x
97 |
98 |
99 |
100 |
101 |
102 |
1.10.x
103 |
104 |
1.0.x-1.6.x
105 |
106 |
107 |
108 |
109 |
110 |
1.11.x
111 |
112 |
1.0.x-1.7.x
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | ## 1.7.0 Updates[¶](#1.7.0updates "Permalink to this headline")
125 |
126 | Stream manager supports automatic data export to AWS S3 and AWS IoT SiteWise, provides new API method to update existing streams, and pause or resume exporting.
127 |
128 |
129 |
130 |
131 |
132 | ## 1.6.0 Updates[¶](#1.6.0updates "Permalink to this headline")
133 |
134 | Added support for StreamManager, see [AWS Docs](https://docs.aws.amazon.com/greengrass/latest/developerguide/stream-manager.html)
135 | for more information.
136 |
137 | ### Compatibility
138 |
139 | StreamManager has adds a new dependency to this package, `cbor==5.0.1`.
140 | Please make sure to include it in your lambda or else the SDK will not function.
141 | In addition to the new dependency, the 1.6.0 version of this SDK now requires NodeJS version 12
142 | or greater since NodeJS 6 and 8 are end-of-life. See [https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html](https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html).
143 |
144 | ### StreamManager Usage
145 |
146 | ```javascript
147 | const {
148 | StreamManagerClient
149 | } = require('aws-greengrass-core-sdk').StreamManager;
150 |
151 | const c = new StreamManagerClient({
152 | onConnectCb: async () => {
153 | try {
154 | // Let's start with something simple.
155 | // Just print out all the available stream names on the server
156 | console.log(await c.listStreams());
157 | } finally {
158 | c.close(); // Always close the client when you're done
159 | }
160 | }
161 | });
162 | ```
163 |
164 |
165 |
166 |
167 |
168 | ## 1.5.0 Updates[¶](#1.5.0updates "Permalink to this headline")
169 |
170 | Added support for publish() parameter queueFullPolicy which can be set to 'AllOrError' to enforce that the published message is either delivered to all subscription destinations or delivered to no destinations and returns an error when Greengrass Core's internal work queue is full.
171 |
172 |
173 |
174 |
175 |
176 | ## 1.4.0 Updates[¶](#1.4.0updates "Permalink to this headline")
177 |
178 | Added support for Node.js 8.10 Lambda runtime. Lambda functions that use Node.js 8.10 runtime can now run on an AWS IoT Greengrass core. (Existing Lambda functions that use Node.js 6.10 runtime can still run on Greengrass core, but they can't be updated after 5/30/2019. Please refer to [AWS Lambda Runtimes Support Policy](https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html).)
179 |
180 |
199 |
200 | ## 1.2.0 Updates[¶](#1.2.0updates "Permalink to this headline")
201 |
202 | SDK and GGC compatibility check takes place in the background.
203 |
204 |
205 |
206 |
207 |
208 | ## 1.1.0 Updates[¶](#1.1.0updates "Permalink to this headline")
209 |
210 | Lambda only accepted payload in JSON format. With this update, Invoking or publishing binary payload to a lambda is supported.
211 |
212 |
213 |
214 |
215 |
216 | ## 1.0.1 Updates[¶](#1.0.1updates "Permalink to this headline")
217 |
218 | Shadow operations were not receiving responses from the local shadow properly. This has been fixed.
219 |
220 | Lambda Invoke function's InvocationType's default value was Event. This has been changed to RequestResponse.
221 |
222 |