Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mock_uss] Do not query operational intents when not deconflicting #243

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 65 additions & 54 deletions monitoring/mock_uss/scdsc/routes_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
from loguru import logger
import requests.exceptions

from monitoring.mock_uss.dynamic_configuration.configuration import get_locality
from uas_standards.astm.f3548.v21 import api
from uas_standards.astm.f3548.v21.api import (
OperationalIntent,
PutOperationalIntentDetailsParameters,
ImplicitSubscriptionParameters,
PutOperationalIntentReferenceParameters,
)
from uas_standards.interuss.automated_testing.scd.v1.api import (
InjectFlightRequest,
InjectFlightResponse,
Expand All @@ -24,35 +30,29 @@
CapabilitiesResponse,
OperationalIntentState,
)
from uas_standards.astm.f3548.v21 import api
from uas_standards.astm.f3548.v21.api import (
OperationalIntent,
PutOperationalIntentDetailsParameters,
ImplicitSubscriptionParameters,
PutOperationalIntentReferenceParameters,
)

from monitoring.mock_uss import webapp, require_config_value
from monitoring.mock_uss.auth import requires_scope
from monitoring.mock_uss.config import KEY_BASE_URL
from monitoring.mock_uss.database import fulfilled_request_ids
from monitoring.mock_uss.dynamic_configuration.configuration import get_locality
from monitoring.mock_uss.scdsc import database, utm_client
from monitoring.mock_uss.scdsc.database import db
from monitoring.mock_uss.scdsc.flight_planning import (
validate_request,
check_for_disallowed_conflicts,
PlanningError,
op_intent_transition_valid,
)
from monitoring.mock_uss.scdsc.routes_scdsc import op_intent_from_flightrecord
from monitoring.monitorlib.geo import Polygon
from monitoring.monitorlib.geotemporal import Volume4D, Volume4DCollection
from monitoring.mock_uss.config import KEY_BASE_URL
from monitoring.monitorlib import versioning
from monitoring.monitorlib.clients import scd as scd_client
from monitoring.monitorlib.fetch import QueryError
from monitoring.monitorlib.geo import Polygon
from monitoring.monitorlib.geotemporal import Volume4D, Volume4DCollection
from monitoring.monitorlib.scd_automated_testing.scd_injection_api import (
SCOPE_SCD_QUALIFIER_INJECT,
)
from monitoring.mock_uss import webapp, require_config_value
from monitoring.mock_uss.auth import requires_scope
from monitoring.mock_uss.scdsc import database, utm_client
from monitoring.mock_uss.scdsc.database import db


require_config_value(KEY_BASE_URL)
Expand Down Expand Up @@ -197,7 +197,7 @@ def log(msg: str):
200,
)

# Check if this is an existing flight being modified
# If this is a change to an existing flight, acquire lock to that flight
log("Acquiring lock for flight")
deadline = datetime.utcnow() + DEADLOCK_TIMEOUT
while True:
Expand All @@ -223,60 +223,71 @@ def log(msg: str):
f"Deadlock in inject_flight while attempting to gain access to flight {flight_id}"
)

# Check the transition is valid
state_transition_from = (
OperationalIntentState(existing_flight.op_intent_reference.state)
if existing_flight
else None
)
state_transition_to = OperationalIntentState(req_body.operational_intent.state)
if not op_intent_transition_valid(state_transition_from, state_transition_to):
return (
InjectFlightResponse(
result=InjectFlightResponseResult.Rejected,
notes=f"Operational intent state transition from {state_transition_from} to {state_transition_to} is invalid",
),
200,
)

step_name = "performing unknown operation"
try:
# Check for operational intents in the DSS
step_name = "querying for operational intents"
log("Obtaining latest operational intent information")
v1 = Volume4DCollection.from_interuss_scd_api(
req_body.operational_intent.volumes
+ req_body.operational_intent.off_nominal_volumes
)
vol4 = v1.bounding_volume.to_f3548v21()
op_intents = query_operational_intents(vol4)

# Check for intersections
step_name = "checking for intersections"
log(
f"Checking for intersections with {', '.join(op_intent.reference.id for op_intent in op_intents)}"
# Check the transition is valid
state_transition_from = (
OperationalIntentState(existing_flight.op_intent_reference.state)
if existing_flight
else None
)
try:
check_for_disallowed_conflicts(
req_body, existing_flight, op_intents, locality, log
)
except PlanningError as e:
state_transition_to = OperationalIntentState(req_body.operational_intent.state)
if not op_intent_transition_valid(state_transition_from, state_transition_to):
return (
InjectFlightResponse(
result=InjectFlightResponseResult.ConflictWithFlight,
notes=str(e),
result=InjectFlightResponseResult.Rejected,
notes=f"Operational intent state transition from {state_transition_from} to {state_transition_to} is invalid",
),
200,
)

if req_body.operational_intent.state in (
OperationalIntentState.Accepted,
OperationalIntentState.Activated,
):
# Check for intersections if the flight is nominal

# Check for operational intents in the DSS
step_name = "querying for operational intents"
log("Obtaining latest operational intent information")
v1 = Volume4DCollection.from_interuss_scd_api(
req_body.operational_intent.volumes
+ req_body.operational_intent.off_nominal_volumes
)
vol4 = v1.bounding_volume.to_f3548v21()
op_intents = query_operational_intents(vol4)

# Check for intersections
step_name = "checking for intersections"
log(
f"Checking for intersections with {', '.join(op_intent.reference.id for op_intent in op_intents)}"
)
try:
check_for_disallowed_conflicts(
req_body, existing_flight, op_intents, locality, log
)
except PlanningError as e:
return (
InjectFlightResponse(
result=InjectFlightResponseResult.ConflictWithFlight,
notes=str(e),
),
200,
)

key = [op.reference.ovn for op in op_intents]
else:
# Flight is not nominal and therefore doesn't need to check intersections
key = []

# Create operational intent in DSS
step_name = "sharing operational intent in DSS"
log("Sharing operational intent with DSS")
base_url = "{}/mock/scd".format(webapp.config[KEY_BASE_URL])
req = PutOperationalIntentReferenceParameters(
extents=req_body.operational_intent.volumes
+ req_body.operational_intent.off_nominal_volumes,
key=[op.reference.ovn for op in op_intents],
key=key,
state=req_body.operational_intent.state,
uss_base_url=base_url,
new_subscription=ImplicitSubscriptionParameters(uss_base_url=base_url),
Expand Down
Loading