openc3-cosmos-cfdp 2.0.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.md +18 -0
- data/README.md +103 -55
- data/Rakefile +12 -0
- data/lib/cfdp.py +564 -0
- data/lib/cfdp.rb +68 -14
- data/lib/cfdp_api.py +302 -0
- data/lib/cfdp_api.rb +55 -9
- data/microservices/CFDP/Gemfile +18 -4
- data/microservices/CFDP/Gemfile.dev +22 -8
- data/microservices/CFDP/Gemfile.prod +18 -4
- data/microservices/CFDP/Rakefile +13 -2
- data/microservices/CFDP/app/controllers/application_controller.rb +2 -2
- data/microservices/CFDP/app/controllers/cfdp_controller.rb +62 -31
- data/microservices/CFDP/app/models/cfdp_checksum.rb +12 -4
- data/microservices/CFDP/app/models/cfdp_crc_checksum.rb +10 -2
- data/microservices/CFDP/app/models/cfdp_mib.rb +173 -32
- data/microservices/CFDP/app/models/cfdp_null_checksum.rb +10 -2
- data/microservices/CFDP/app/models/cfdp_pdu.rb +96 -20
- data/microservices/CFDP/app/models/cfdp_receive_transaction.rb +139 -11
- data/microservices/CFDP/app/models/cfdp_source_transaction.rb +433 -93
- data/microservices/CFDP/app/models/cfdp_topic.rb +2 -2
- data/microservices/CFDP/app/models/cfdp_transaction.rb +174 -4
- data/microservices/CFDP/app/models/cfdp_user.rb +216 -73
- data/microservices/CFDP/config/routes.rb +1 -0
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_ack.rb +7 -6
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_eof.rb +1 -2
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_file_data.rb +2 -25
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_finished.rb +8 -7
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_keep_alive.rb +7 -6
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_metadata.rb +1 -2
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_nak.rb +7 -6
- data/microservices/CFDP/lib/cfdp_pdu/cfdp_pdu_prompt.rb +1 -2
- data/microservices/CFDP/spec/controllers/cfdp_controller_spec.rb +226 -1
- data/microservices/CFDP/spec/models/cfdp_checksum_spec.rb +239 -0
- data/microservices/CFDP/spec/models/cfdp_crc_checksum_spec.rb +16 -13
- data/microservices/CFDP/spec/models/cfdp_mib_spec.rb +880 -138
- data/microservices/CFDP/spec/models/cfdp_null_checksum_spec.rb +111 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_file_data_spec.rb +48 -0
- data/microservices/CFDP/spec/models/cfdp_pdu_nak_spec.rb +2 -2
- data/microservices/CFDP/spec/models/cfdp_pdu_spec.rb +129 -0
- data/microservices/CFDP/spec/models/cfdp_receive_transaction_spec.rb +109 -10
- data/microservices/CFDP/spec/models/cfdp_source_transaction_spec.rb +357 -0
- data/microservices/CFDP/spec/models/cfdp_transaction_spec.rb +282 -5
- data/microservices/CFDP/spec/models/cfdp_user_spec.rb +462 -20
- data/microservices/CFDP/spec/requests/cfdp_spec.rb +92 -43
- data/microservices/CFDP/spec/spec_helper.rb +34 -3
- data/plugin.txt +55 -4
- data/public/store_img.png +0 -0
- data/pyproject.toml +70 -0
- data/targets/CFDPTEST/procedures/cfdp_test_suite.py +179 -0
- data/targets/CFDPTEST/procedures/cfdp_test_suite.rb +2 -2
- data/targets/CFDPTEST/procedures/interrupt_test.rb +31 -0
- metadata +25 -12
- data/LICENSE.txt +0 -18
data/lib/cfdp_api.py
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Copyright 2026 OpenC3, Inc.
|
|
2
|
+
# All Rights Reserved.
|
|
3
|
+
#
|
|
4
|
+
# Licensed for Evaluation and Educational Use
|
|
5
|
+
#
|
|
6
|
+
# This file may only be used commercially under the terms of a commercial license
|
|
7
|
+
# purchased from OpenC3, Inc.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
#
|
|
13
|
+
# The development of this software was funded in-whole or in-part by MethaneSAT LLC.
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
|
|
17
|
+
from openc3.environment import OPENC3_SCOPE
|
|
18
|
+
from openc3.io.json_api import JsonApi
|
|
19
|
+
|
|
20
|
+
# Usage:
|
|
21
|
+
#
|
|
22
|
+
# Note: Recommend using the methods in cfdp.py rather than this file directly
|
|
23
|
+
#
|
|
24
|
+
# In ScriptRunner:
|
|
25
|
+
# from cfdp_api import CfdpApi
|
|
26
|
+
# api = CfdpApi()
|
|
27
|
+
# api.put(...)
|
|
28
|
+
#
|
|
29
|
+
# Outside cluster - Core
|
|
30
|
+
# os.environ['OPENC3_SCOPE'] = 'DEFAULT'
|
|
31
|
+
# os.environ['OPENC3_API_PASSWORD'] = 'password'
|
|
32
|
+
# from cfdp_api import CfdpApi
|
|
33
|
+
# api = CfdpApi(url="http://127.0.0.1:2900/cfdp")
|
|
34
|
+
# api.put(...)
|
|
35
|
+
#
|
|
36
|
+
# Outside cluster - Enterprise
|
|
37
|
+
# os.environ['OPENC3_SCOPE'] = 'DEFAULT'
|
|
38
|
+
# os.environ['OPENC3_KEYCLOAK_URL'] = 'http://127.0.0.1:2900/auth'
|
|
39
|
+
# os.environ['OPENC3_API_USER'] = 'operator'
|
|
40
|
+
# os.environ['OPENC3_API_PASSWORD'] = 'operator'
|
|
41
|
+
# from cfdp_api import CfdpApi
|
|
42
|
+
# api = CfdpApi(url="http://127.0.0.1:2900/cfdp")
|
|
43
|
+
# api.put(...)
|
|
44
|
+
#
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class CfdpApi(JsonApi):
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
microservice_name="CFDP",
|
|
51
|
+
prefix="/cfdp",
|
|
52
|
+
port=2905,
|
|
53
|
+
schema="http",
|
|
54
|
+
hostname=None,
|
|
55
|
+
timeout=5.0,
|
|
56
|
+
url=None,
|
|
57
|
+
scope=OPENC3_SCOPE,
|
|
58
|
+
):
|
|
59
|
+
super().__init__(
|
|
60
|
+
microservice_name=microservice_name,
|
|
61
|
+
prefix=prefix,
|
|
62
|
+
port=port,
|
|
63
|
+
schema=schema,
|
|
64
|
+
hostname=hostname,
|
|
65
|
+
timeout=timeout,
|
|
66
|
+
url=url,
|
|
67
|
+
scope=scope,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def put(
|
|
71
|
+
self,
|
|
72
|
+
destination_entity_id,
|
|
73
|
+
source_file_name,
|
|
74
|
+
destination_file_name,
|
|
75
|
+
transmission_mode=None,
|
|
76
|
+
closure_requested=None,
|
|
77
|
+
filestore_requests=None,
|
|
78
|
+
fault_handler_overrides=None,
|
|
79
|
+
flow_label=None,
|
|
80
|
+
segmentation_control="NOT_PRESERVED",
|
|
81
|
+
messages_to_user=None,
|
|
82
|
+
remote_entity_id=None, # Used to indicate proxy put
|
|
83
|
+
scope=OPENC3_SCOPE,
|
|
84
|
+
):
|
|
85
|
+
try:
|
|
86
|
+
endpoint = "/put"
|
|
87
|
+
data = {
|
|
88
|
+
"destination_entity_id": int(destination_entity_id),
|
|
89
|
+
"source_file_name": source_file_name,
|
|
90
|
+
"destination_file_name": destination_file_name,
|
|
91
|
+
"transmission_mode": transmission_mode,
|
|
92
|
+
"closure_requested": closure_requested,
|
|
93
|
+
"filestore_requests": filestore_requests if filestore_requests is not None else [],
|
|
94
|
+
"fault_handler_overrides": fault_handler_overrides
|
|
95
|
+
if fault_handler_overrides is not None
|
|
96
|
+
else [],
|
|
97
|
+
"messages_to_user": messages_to_user if messages_to_user is not None else [],
|
|
98
|
+
"flow_label": flow_label,
|
|
99
|
+
"segmentation_control": segmentation_control,
|
|
100
|
+
}
|
|
101
|
+
if remote_entity_id is not None:
|
|
102
|
+
data["remote_entity_id"] = int(remote_entity_id)
|
|
103
|
+
response = self._request("post", endpoint, data=data, scope=scope)
|
|
104
|
+
if response is None or response.status_code != 200:
|
|
105
|
+
if response is not None:
|
|
106
|
+
raise RuntimeError(f"CFDP put error: {response.status_code}: {response.text}")
|
|
107
|
+
else:
|
|
108
|
+
raise RuntimeError("CFDP put failed")
|
|
109
|
+
return response.text
|
|
110
|
+
except Exception as error:
|
|
111
|
+
raise RuntimeError(f"CFDP put failed due to {repr(error)}") from error
|
|
112
|
+
|
|
113
|
+
def put_dir(
|
|
114
|
+
self,
|
|
115
|
+
destination_entity_id,
|
|
116
|
+
source_directory_name,
|
|
117
|
+
transmission_mode=None,
|
|
118
|
+
closure_requested=None,
|
|
119
|
+
filestore_requests=None,
|
|
120
|
+
fault_handler_overrides=None,
|
|
121
|
+
flow_label=None,
|
|
122
|
+
segmentation_control="NOT_PRESERVED",
|
|
123
|
+
messages_to_user=None,
|
|
124
|
+
remote_entity_id=None, # Used to indicate proxy put
|
|
125
|
+
scope=OPENC3_SCOPE,
|
|
126
|
+
):
|
|
127
|
+
try:
|
|
128
|
+
endpoint = "/put_dir"
|
|
129
|
+
data = {
|
|
130
|
+
"destination_entity_id": int(destination_entity_id),
|
|
131
|
+
"source_directory_name": source_directory_name,
|
|
132
|
+
"transmission_mode": transmission_mode,
|
|
133
|
+
"closure_requested": closure_requested,
|
|
134
|
+
"filestore_requests": filestore_requests if filestore_requests is not None else [],
|
|
135
|
+
"fault_handler_overrides": fault_handler_overrides
|
|
136
|
+
if fault_handler_overrides is not None
|
|
137
|
+
else [],
|
|
138
|
+
"messages_to_user": messages_to_user if messages_to_user is not None else [],
|
|
139
|
+
"flow_label": flow_label,
|
|
140
|
+
"segmentation_control": segmentation_control,
|
|
141
|
+
}
|
|
142
|
+
if remote_entity_id is not None:
|
|
143
|
+
data["remote_entity_id"] = int(remote_entity_id)
|
|
144
|
+
response = self._request("post", endpoint, data=data, scope=scope)
|
|
145
|
+
if response is None or response.status_code != 200:
|
|
146
|
+
if response is not None:
|
|
147
|
+
raise RuntimeError(
|
|
148
|
+
f"CFDP put_dir error: {response.status_code}: {response.text}"
|
|
149
|
+
)
|
|
150
|
+
else:
|
|
151
|
+
raise RuntimeError("CFDP put_dir failed")
|
|
152
|
+
return json.loads(response.text)
|
|
153
|
+
except Exception as error:
|
|
154
|
+
raise RuntimeError(f"CFDP put_dir failed due to {repr(error)}") from error
|
|
155
|
+
|
|
156
|
+
def cancel(self, transaction_id, remote_entity_id=None, scope=OPENC3_SCOPE):
|
|
157
|
+
return self.transaction_id_post(
|
|
158
|
+
method_name="cancel",
|
|
159
|
+
transaction_id=transaction_id,
|
|
160
|
+
remote_entity_id=remote_entity_id,
|
|
161
|
+
scope=scope,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def suspend(self, transaction_id, remote_entity_id=None, scope=OPENC3_SCOPE):
|
|
165
|
+
return self.transaction_id_post(
|
|
166
|
+
method_name="suspend",
|
|
167
|
+
transaction_id=transaction_id,
|
|
168
|
+
remote_entity_id=remote_entity_id,
|
|
169
|
+
scope=scope,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def resume(self, transaction_id, remote_entity_id=None, scope=OPENC3_SCOPE):
|
|
173
|
+
return self.transaction_id_post(
|
|
174
|
+
method_name="resume",
|
|
175
|
+
transaction_id=transaction_id,
|
|
176
|
+
remote_entity_id=remote_entity_id,
|
|
177
|
+
scope=scope,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def report(
|
|
181
|
+
self, transaction_id, remote_entity_id=None, report_file_name=None, scope=OPENC3_SCOPE
|
|
182
|
+
):
|
|
183
|
+
return self.transaction_id_post(
|
|
184
|
+
method_name="report",
|
|
185
|
+
transaction_id=transaction_id,
|
|
186
|
+
remote_entity_id=remote_entity_id,
|
|
187
|
+
report_file_name=report_file_name,
|
|
188
|
+
scope=scope,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
def subscribe(self, scope=OPENC3_SCOPE):
|
|
192
|
+
try:
|
|
193
|
+
endpoint = "/subscribe"
|
|
194
|
+
response = self._request("get", endpoint, scope=scope)
|
|
195
|
+
if response is None or response.status_code != 200:
|
|
196
|
+
if response is not None:
|
|
197
|
+
raise RuntimeError(
|
|
198
|
+
f"CFDP subscribe error: {response.status_code}: {response.text}"
|
|
199
|
+
)
|
|
200
|
+
else:
|
|
201
|
+
raise RuntimeError("CFDP subscribe failed")
|
|
202
|
+
# Most recent topic id
|
|
203
|
+
return response.text
|
|
204
|
+
except Exception as error:
|
|
205
|
+
raise RuntimeError(f"CFDP subscribe failed due to {repr(error)}") from error
|
|
206
|
+
|
|
207
|
+
def indications(self, transaction_id=None, continuation=None, limit=100, scope=OPENC3_SCOPE):
|
|
208
|
+
try:
|
|
209
|
+
endpoint = "/indications"
|
|
210
|
+
if transaction_id:
|
|
211
|
+
endpoint += "/" + str(transaction_id)
|
|
212
|
+
query = {}
|
|
213
|
+
if continuation:
|
|
214
|
+
query["continuation"] = continuation
|
|
215
|
+
if limit:
|
|
216
|
+
query["limit"] = limit
|
|
217
|
+
response = self._request("get", endpoint, query=query, scope=scope)
|
|
218
|
+
if response is None or response.status_code != 200:
|
|
219
|
+
if response is not None:
|
|
220
|
+
raise RuntimeError(
|
|
221
|
+
f"CFDP indications error: {response.status_code}: {response.text}"
|
|
222
|
+
)
|
|
223
|
+
else:
|
|
224
|
+
raise RuntimeError("CFDP indications failed")
|
|
225
|
+
# Dict of continuation, and indications array
|
|
226
|
+
return json.loads(response.text)
|
|
227
|
+
except Exception as error:
|
|
228
|
+
raise RuntimeError(f"CFDP indications failed due to {repr(error)}") from error
|
|
229
|
+
|
|
230
|
+
def directory_listing(
|
|
231
|
+
self, remote_entity_id, directory_name, directory_file_name, scope=OPENC3_SCOPE
|
|
232
|
+
):
|
|
233
|
+
try:
|
|
234
|
+
endpoint = "/directorylisting"
|
|
235
|
+
data = {
|
|
236
|
+
"remote_entity_id": remote_entity_id,
|
|
237
|
+
"directory_name": directory_name,
|
|
238
|
+
"directory_file_name": directory_file_name,
|
|
239
|
+
}
|
|
240
|
+
response = self._request("post", endpoint, data=data, scope=scope)
|
|
241
|
+
if response is None or response.status_code != 200:
|
|
242
|
+
if response is not None:
|
|
243
|
+
raise RuntimeError(
|
|
244
|
+
f"CFDP directory listing error: {response.status_code}: {response.text}"
|
|
245
|
+
)
|
|
246
|
+
else:
|
|
247
|
+
raise RuntimeError("CFDP directory listing failed")
|
|
248
|
+
return response.text
|
|
249
|
+
except Exception as error:
|
|
250
|
+
raise RuntimeError(f"CFDP directory listing failed due to {repr(error)}") from error
|
|
251
|
+
|
|
252
|
+
def transactions(self, active=True, scope=OPENC3_SCOPE):
|
|
253
|
+
try:
|
|
254
|
+
endpoint = "/transactions"
|
|
255
|
+
query = {}
|
|
256
|
+
if active:
|
|
257
|
+
query["active"] = active
|
|
258
|
+
response = self._request("get", endpoint, query=query, scope=scope)
|
|
259
|
+
if response is None or response.status_code != 200:
|
|
260
|
+
if response is not None:
|
|
261
|
+
raise RuntimeError(
|
|
262
|
+
f"CFDP transactions error: {response.status_code}: {response.text}"
|
|
263
|
+
)
|
|
264
|
+
else:
|
|
265
|
+
raise RuntimeError("CFDP transactions failed")
|
|
266
|
+
# Array of Transaction dicts
|
|
267
|
+
return json.loads(response.text)
|
|
268
|
+
except Exception as error:
|
|
269
|
+
raise RuntimeError(f"CFDP transactions failed due to {repr(error)}") from error
|
|
270
|
+
|
|
271
|
+
# private
|
|
272
|
+
|
|
273
|
+
def transaction_id_post(
|
|
274
|
+
self,
|
|
275
|
+
method_name,
|
|
276
|
+
transaction_id,
|
|
277
|
+
remote_entity_id=None,
|
|
278
|
+
report_file_name=None,
|
|
279
|
+
scope=OPENC3_SCOPE,
|
|
280
|
+
):
|
|
281
|
+
try:
|
|
282
|
+
endpoint = f"/{method_name}"
|
|
283
|
+
data = {"transaction_id": str(transaction_id)}
|
|
284
|
+
if remote_entity_id is not None:
|
|
285
|
+
data["remote_entity_id"] = remote_entity_id
|
|
286
|
+
if report_file_name is not None:
|
|
287
|
+
data["report_file_name"] = report_file_name
|
|
288
|
+
response = self._request("post", endpoint, data=data, scope=scope)
|
|
289
|
+
if response is None or response.status_code != 200:
|
|
290
|
+
if response is not None:
|
|
291
|
+
raise RuntimeError(
|
|
292
|
+
f"CFDP {method_name} error: {response.status_code}: {response.text}"
|
|
293
|
+
)
|
|
294
|
+
else:
|
|
295
|
+
raise RuntimeError(f"CFDP {method_name} failed")
|
|
296
|
+
# String of "null" results from the controller "render json: null"
|
|
297
|
+
if response.text == "null":
|
|
298
|
+
return None
|
|
299
|
+
else:
|
|
300
|
+
return response.text
|
|
301
|
+
except Exception as error:
|
|
302
|
+
raise RuntimeError(f"CFDP {method_name} failed due to {repr(error)}") from error
|
data/lib/cfdp_api.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# encoding: ascii-8bit
|
|
2
2
|
|
|
3
|
-
# Copyright
|
|
3
|
+
# Copyright 2026 OpenC3, Inc.
|
|
4
4
|
# All Rights Reserved.
|
|
5
5
|
#
|
|
6
6
|
# Licensed for Evaluation and Educational Use
|
|
@@ -26,7 +26,7 @@ require 'openc3/io/json_api'
|
|
|
26
26
|
# api = CfdpApi.new()
|
|
27
27
|
# api.put(...)
|
|
28
28
|
#
|
|
29
|
-
# Outside cluster -
|
|
29
|
+
# Outside cluster - Core
|
|
30
30
|
# $openc3_scope = 'DEFAULT'
|
|
31
31
|
# ENV['OPENC3_API_PASSWORD'] = 'password'
|
|
32
32
|
# require 'cfdp_api'
|
|
@@ -87,20 +87,61 @@ class CfdpApi < OpenC3::JsonApi
|
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
+
def put_dir(
|
|
91
|
+
destination_entity_id:,
|
|
92
|
+
source_directory_name:,
|
|
93
|
+
transmission_mode: nil,
|
|
94
|
+
closure_requested: nil,
|
|
95
|
+
filestore_requests: [],
|
|
96
|
+
fault_handler_overrides: [],
|
|
97
|
+
flow_label: nil,
|
|
98
|
+
segmentation_control: "NOT_PRESERVED",
|
|
99
|
+
messages_to_user: [],
|
|
100
|
+
remote_entity_id: nil, # Used to indicate proxy put
|
|
101
|
+
scope: $openc3_scope)
|
|
102
|
+
|
|
103
|
+
begin
|
|
104
|
+
endpoint = "/put_dir"
|
|
105
|
+
data = {
|
|
106
|
+
"destination_entity_id" => destination_entity_id.to_i,
|
|
107
|
+
"source_directory_name" => source_directory_name,
|
|
108
|
+
"transmission_mode" => transmission_mode,
|
|
109
|
+
"closure_requested" => closure_requested,
|
|
110
|
+
"filestore_requests" => filestore_requests,
|
|
111
|
+
"fault_handler_overrides" => fault_handler_overrides,
|
|
112
|
+
"messages_to_user" => messages_to_user,
|
|
113
|
+
"flow_label" => flow_label,
|
|
114
|
+
"segmentation_control" => segmentation_control
|
|
115
|
+
}
|
|
116
|
+
data["remote_entity_id"] = remote_entity_id.to_i if remote_entity_id
|
|
117
|
+
response = _request('post', endpoint, data: data, scope: scope)
|
|
118
|
+
if response.nil? || response.code != 200
|
|
119
|
+
if response
|
|
120
|
+
raise "CFDP put_dir error: #{response.code}: #{response.body}"
|
|
121
|
+
else
|
|
122
|
+
raise "CFDP put_dir failed"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
|
126
|
+
rescue => error
|
|
127
|
+
raise "CFDP put_dir failed due to #{error.formatted}"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
90
131
|
def cancel(transaction_id:, remote_entity_id: nil, scope: $openc3_scope)
|
|
91
|
-
transaction_id_post(method_name: "cancel", transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope:
|
|
132
|
+
transaction_id_post(method_name: "cancel", transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
|
|
92
133
|
end
|
|
93
134
|
|
|
94
135
|
def suspend(transaction_id:, remote_entity_id: nil, scope: $openc3_scope)
|
|
95
|
-
transaction_id_post(method_name: "suspend", transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope:
|
|
136
|
+
transaction_id_post(method_name: "suspend", transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
|
|
96
137
|
end
|
|
97
138
|
|
|
98
139
|
def resume(transaction_id:, remote_entity_id: nil, scope: $openc3_scope)
|
|
99
|
-
transaction_id_post(method_name: "resume", transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope:
|
|
140
|
+
transaction_id_post(method_name: "resume", transaction_id: transaction_id, remote_entity_id: remote_entity_id, scope: scope)
|
|
100
141
|
end
|
|
101
142
|
|
|
102
143
|
def report(transaction_id:, remote_entity_id: nil, report_file_name: nil, scope: $openc3_scope)
|
|
103
|
-
transaction_id_post(method_name: "report", transaction_id: transaction_id, remote_entity_id: remote_entity_id, report_file_name: report_file_name, scope:
|
|
144
|
+
transaction_id_post(method_name: "report", transaction_id: transaction_id, remote_entity_id: remote_entity_id, report_file_name: report_file_name, scope: scope)
|
|
104
145
|
end
|
|
105
146
|
|
|
106
147
|
def subscribe(scope: $openc3_scope)
|
|
@@ -137,7 +178,7 @@ class CfdpApi < OpenC3::JsonApi
|
|
|
137
178
|
end
|
|
138
179
|
end
|
|
139
180
|
# Hash of continuation, and indications array
|
|
140
|
-
return JSON.parse(response.body)
|
|
181
|
+
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
|
141
182
|
rescue => error
|
|
142
183
|
raise "CFDP indications failed due to #{error.formatted}"
|
|
143
184
|
end
|
|
@@ -175,7 +216,7 @@ class CfdpApi < OpenC3::JsonApi
|
|
|
175
216
|
end
|
|
176
217
|
end
|
|
177
218
|
# Array of Transaction Hashes
|
|
178
|
-
return JSON.parse(response.body)
|
|
219
|
+
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
|
179
220
|
rescue => error
|
|
180
221
|
raise "CFDP transactions failed due to #{error.formatted}"
|
|
181
222
|
end
|
|
@@ -197,7 +238,12 @@ class CfdpApi < OpenC3::JsonApi
|
|
|
197
238
|
raise "CFDP #{method_name} failed"
|
|
198
239
|
end
|
|
199
240
|
end
|
|
200
|
-
|
|
241
|
+
# String of "null" results from the controller "render json: null"
|
|
242
|
+
if response.body == "null"
|
|
243
|
+
return nil
|
|
244
|
+
else
|
|
245
|
+
return response.body
|
|
246
|
+
end
|
|
201
247
|
rescue => error
|
|
202
248
|
raise "CFDP #{method_name} failed due to #{error.formatted}"
|
|
203
249
|
end
|
data/microservices/CFDP/Gemfile
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2026 OpenC3, Inc.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# Licensed for Evaluation and Educational Use
|
|
7
|
+
#
|
|
8
|
+
# This file may only be used commercially under the terms of a commercial license
|
|
9
|
+
# purchased from OpenC3, Inc.
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
|
|
1
15
|
source ENV['RUBYGEMS_URL'] || "https://rubygems.org"
|
|
2
16
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|
3
17
|
|
|
4
18
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
|
5
|
-
gem 'rails', '
|
|
19
|
+
gem 'rails', '>= 7.1.0'
|
|
6
20
|
|
|
7
21
|
# Reduces boot times through caching; required in config/boot.rb
|
|
8
22
|
gem 'bootsnap', '>= 1.9.3', require: false
|
|
9
23
|
|
|
10
24
|
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
|
|
11
|
-
gem 'rack-cors', '
|
|
25
|
+
gem 'rack-cors', '>= 2.0'
|
|
12
26
|
|
|
13
27
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
|
14
28
|
gem 'tzinfo-data'
|
|
@@ -21,9 +35,9 @@ if ENV['OPENC3_DEVEL']
|
|
|
21
35
|
elsif ENV['OPENC3_PATH']
|
|
22
36
|
gem 'openc3', :path => ENV['OPENC3_PATH']
|
|
23
37
|
else
|
|
24
|
-
gem 'openc3', '>=
|
|
38
|
+
gem 'openc3', '>= 6.10.4'
|
|
25
39
|
end
|
|
26
40
|
|
|
27
41
|
if ENV['OPENC3_ENTERPRISE_TAG']
|
|
28
|
-
gem 'openc3-enterprise', '>=
|
|
42
|
+
gem 'openc3-enterprise', '>= 6.10.4'
|
|
29
43
|
end
|
|
@@ -1,25 +1,39 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2026 OpenC3, Inc.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# Licensed for Evaluation and Educational Use
|
|
7
|
+
#
|
|
8
|
+
# This file may only be used commercially under the terms of a commercial license
|
|
9
|
+
# purchased from OpenC3, Inc.
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
|
|
1
15
|
source ENV['RUBYGEMS_URL'] || "https://rubygems.org"
|
|
2
16
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|
3
17
|
|
|
4
18
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
|
5
|
-
gem 'rails', '
|
|
19
|
+
gem 'rails', '>= 7.1.0'
|
|
6
20
|
|
|
7
21
|
# Reduces boot times through caching; required in config/boot.rb
|
|
8
22
|
gem 'bootsnap', '>= 1.9.3', require: false
|
|
9
23
|
|
|
10
24
|
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
|
|
11
|
-
gem 'rack-cors', '
|
|
25
|
+
gem 'rack-cors', '>= 2.0'
|
|
12
26
|
|
|
13
27
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
|
14
28
|
gem 'tzinfo-data'
|
|
15
29
|
|
|
16
30
|
group :development, :test do
|
|
17
|
-
gem 'rspec-rails', '~>
|
|
18
|
-
gem 'simplecov', '~>
|
|
19
|
-
gem 'simplecov-cobertura', '~>
|
|
31
|
+
gem 'rspec-rails', '~> 8.0'
|
|
32
|
+
gem 'simplecov', '~> 1.1'
|
|
33
|
+
gem 'simplecov-cobertura', '~> 4.0'
|
|
20
34
|
end
|
|
21
35
|
group :test do
|
|
22
|
-
gem 'mock_redis', '
|
|
36
|
+
gem 'mock_redis', '~> 0.47'
|
|
23
37
|
end
|
|
24
38
|
|
|
25
39
|
if ENV['OPENC3_DEVEL']
|
|
@@ -27,9 +41,9 @@ if ENV['OPENC3_DEVEL']
|
|
|
27
41
|
elsif ENV['OPENC3_PATH']
|
|
28
42
|
gem 'openc3', :path => ENV['OPENC3_PATH']
|
|
29
43
|
else
|
|
30
|
-
gem 'openc3', '>=
|
|
44
|
+
gem 'openc3', '>= 6.10.4'
|
|
31
45
|
end
|
|
32
46
|
|
|
33
47
|
if ENV['OPENC3_ENTERPRISE_TAG']
|
|
34
|
-
gem 'openc3-enterprise', '>=
|
|
48
|
+
gem 'openc3-enterprise', '>= 6.10.4'
|
|
35
49
|
end
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2026 OpenC3, Inc.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# Licensed for Evaluation and Educational Use
|
|
7
|
+
#
|
|
8
|
+
# This file may only be used commercially under the terms of a commercial license
|
|
9
|
+
# purchased from OpenC3, Inc.
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
|
|
1
15
|
source ENV['RUBYGEMS_URL'] || "https://rubygems.org"
|
|
2
16
|
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|
3
17
|
|
|
4
18
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
|
5
|
-
gem 'rails', '
|
|
19
|
+
gem 'rails', '>= 7.1.0'
|
|
6
20
|
|
|
7
21
|
# Reduces boot times through caching; required in config/boot.rb
|
|
8
22
|
gem 'bootsnap', '>= 1.9.3', require: false
|
|
9
23
|
|
|
10
24
|
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
|
|
11
|
-
gem 'rack-cors', '
|
|
25
|
+
gem 'rack-cors', '>= 2.0'
|
|
12
26
|
|
|
13
27
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
|
14
28
|
gem 'tzinfo-data'
|
|
@@ -21,9 +35,9 @@ if ENV['OPENC3_DEVEL']
|
|
|
21
35
|
elsif ENV['OPENC3_PATH']
|
|
22
36
|
gem 'openc3', :path => ENV['OPENC3_PATH']
|
|
23
37
|
else
|
|
24
|
-
gem 'openc3', '>=
|
|
38
|
+
gem 'openc3', '>= 6.10.4'
|
|
25
39
|
end
|
|
26
40
|
|
|
27
41
|
if ENV['OPENC3_ENTERPRISE_TAG']
|
|
28
|
-
gem 'openc3-enterprise', '>=
|
|
42
|
+
gem 'openc3-enterprise', '>= 6.10.4'
|
|
29
43
|
end
|
data/microservices/CFDP/Rakefile
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# encoding: ascii-8bit
|
|
2
|
+
|
|
3
|
+
# Copyright 2026 OpenC3, Inc.
|
|
4
|
+
# All Rights Reserved.
|
|
5
|
+
#
|
|
6
|
+
# Licensed for Evaluation and Educational Use
|
|
7
|
+
#
|
|
8
|
+
# This file may only be used commercially under the terms of a commercial license
|
|
9
|
+
# purchased from OpenC3, Inc.
|
|
10
|
+
#
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
3
14
|
|
|
4
15
|
require_relative 'config/application'
|
|
5
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# encoding: ascii-8bit
|
|
2
2
|
|
|
3
|
-
# Copyright
|
|
3
|
+
# Copyright 2026 OpenC3, Inc.
|
|
4
4
|
# All Rights Reserved.
|
|
5
5
|
#
|
|
6
6
|
# Licensed for Evaluation and Educational Use
|
|
@@ -21,7 +21,7 @@ class ApplicationController < ActionController::API
|
|
|
21
21
|
|
|
22
22
|
private
|
|
23
23
|
|
|
24
|
-
# Authorize and rescue the possible
|
|
24
|
+
# Authorize and rescue the possible exceptions
|
|
25
25
|
# @return [Boolean] true if authorize successful
|
|
26
26
|
def authorization(permission, target_name: nil, packet_name: nil, interface_name: nil, router_name: nil)
|
|
27
27
|
begin
|