Skip to content

Commit

Permalink
naive timestamp: (#131)
Browse files Browse the repository at this point in the history
naive timestamp fix:

Fixed issue with reusing the same IncidentStatus instance timestamp
1:
timestamp=naive_utcnow() // api/routes.py: L50;
2:
black formatter cosmetic changes

Reviewed-by: Vladimir Hasko <[email protected]>
  • Loading branch information
bakhterets authored Nov 12, 2024
1 parent 2ee57f9 commit 0d6a1fb
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 70 deletions.
80 changes: 35 additions & 45 deletions app/api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@

def inc_by_impact(incidents, impact):
incident_match = next(
(incident for incident in incidents if incident.impact == impact),
None
(incident for incident in incidents if incident.impact == impact), None
)
return incident_match

Expand All @@ -48,24 +47,20 @@ def update_incident_status(incident, text_status, status="SYSTEM"):
incident_id=incident.id,
text=text_status,
status=status,
timestamp=naive_utcnow(),
)
current_app.logger.debug(f"UPDATE_STATUS: {text_status}")
db.session.add(update)


def add_component_to_incident(
target_component,
incident,
comp_with_attrs=None
target_component, incident, comp_with_attrs=None
):
current_app.logger.debug(
f"Add {target_component} to the incident: {incident}"
)
update_incident_status(
incident,
(
f"{comp_with_attrs} added to {incident.text}"
)
incident, (f"{comp_with_attrs} added to {incident.text}")
)
incident.components.append(target_component)
db.session.commit()
Expand All @@ -92,22 +87,20 @@ def handling_statuses(
new_incident=None,
action=None,
impact=None,
impacts=None
impacts=None,
):
if action:
url_s = url_for('web.incident', incident_id=incident.id)
url_s = url_for("web.incident", incident_id=incident.id)
link_s = f"<a href='{url_s}'>{incident.text}</a>"

if action == "move":
if dst_incident:
url_d = url_for('web.incident', incident_id=dst_incident.id)
url_d = url_for("web.incident", incident_id=dst_incident.id)
link_d = f"<a href='{url_d}'>{dst_incident.text}</a>"
update_s = (
f"{comp_with_attrs} moved to {link_d}"
)
update_s = f"{comp_with_attrs} moved to {link_d}"
update_d = f"{comp_with_attrs} moved from {link_s}"
elif new_incident:
url_d = url_for('web.incident', incident_id=new_incident.id)
url_d = url_for("web.incident", incident_id=new_incident.id)
link_d = f"<a href='{url_d}'>{new_incident.text}</a>"
update_s = f"{comp_with_attrs} moved to {link_d}"
update_n = f"{comp_with_attrs} moved from {link_s}"
Expand All @@ -131,12 +124,11 @@ def handling_incidents(
src_incident,
dst_incident=None,
text=None,
comp_with_attrs=None
comp_with_attrs=None,
):
if len(src_incident.components) == 1 and dst_incident:
current_app.logger.debug(
f"{target_component} "
f"moved to: '{dst_incident.text}'"
f"{target_component} " f"moved to: '{dst_incident.text}'"
)
current_app.logger.debug(f"{src_incident.text} CLOSED")
src_incident.end_date = naive_utcnow()
Expand All @@ -145,7 +137,7 @@ def handling_incidents(
src_incident,
comp_with_attrs,
dst_incident=dst_incident,
action="move"
action="move",
)
db.session.commit()
update_incident_status(src_incident, "CLOSED BY SYSTEM")
Expand All @@ -165,7 +157,7 @@ def handling_incidents(
src_incident,
action="change_impact",
impact=impact,
impacts=impacts
impacts=impacts,
)
src_incident.impact = impact
db.session.commit()
Expand All @@ -181,7 +173,7 @@ def handling_incidents(
src_incident,
comp_with_attrs,
dst_incident=dst_incident,
action="move"
action="move",
)
db.session.commit()
return dst_incident
Expand Down Expand Up @@ -221,7 +213,7 @@ def get_request_info():
return (
f"Request method: {request.method}, "
f"Request path: {request.path}",
f"Client address: {request.remote_addr}"
f"Client address: {request.remote_addr}",
)

@bp.arguments(ComponentSearchQueryArgs, location="query")
Expand Down Expand Up @@ -251,8 +243,9 @@ def get(self, search_args):
else:
attribute = None
component_schema = ComponentSchema()
cache_key = (f"component_status:{name if name else 'all'}"
f"{attribute if attribute else ''}"
cache_key = (
f"component_status:{name if name else 'all'}"
f"{attribute if attribute else ''}"
)

cached_component = get_elements_from_cache(cache_key)
Expand Down Expand Up @@ -344,9 +337,7 @@ def post(self, data):
comp_name = target_component.name
comp_attributes = target_component.attributes
comp_attributes_str = ", ".join(
[
f"{attr.value}" for attr in comp_attributes
]
[f"{attr.value}" for attr in comp_attributes]
)
comp_with_attrs = f"{comp_name} ({comp_attributes_str})"

Expand All @@ -365,8 +356,10 @@ def post(self, data):
return maintenance
incidents_by_user = Incident.get_active_m()
for incident in incidents_by_user:
if target_component in incident.components and \
impact <= incident.impact:
if (
target_component in incident.components
and impact <= incident.impact
):
current_app.logger.debug(
"Incident is active for the component, "
"requested impact equal or less - not modifying "
Expand All @@ -375,13 +368,12 @@ def post(self, data):
existing_incident = incident
response = {
"message": (
"Incident with this the component "
"already exists"
"Incident with this the component " "already exists"
),
"targetComponent": comp_with_attrs,
"existingIncidentId": existing_incident.id,
"existingIncidentTitle": existing_incident.text,
"details": "Check your request parameters"
"details": "Check your request parameters",
}
return jsonify(response), 409

Expand Down Expand Up @@ -414,16 +406,14 @@ def post(self, data):
for incident in incidents:
if target_component in incident.components:
if impact > incident.impact:
return (
handling_incidents(
target_component,
impact,
impacts,
incident,
incident_match,
text,
comp_with_attrs,
)
return handling_incidents(
target_component,
impact,
impacts,
incident,
incident_match,
text,
comp_with_attrs,
)
else:
# For the component incident is already open -
Expand All @@ -441,7 +431,7 @@ def post(self, data):
"targetComponent": comp_with_attrs,
"existingIncidentId": existing_incident.id,
"existingIncidentTitle": existing_incident.text,
"details": "Check your request parameters"
"details": "Check your request parameters",
}
return jsonify(response), 409

Expand All @@ -453,7 +443,7 @@ def get_request_info():
return (
f"Request method: {request.method}, "
f"Request path: {request.path}",
f"Client address: {request.remote_addr}"
f"Client address: {request.remote_addr}",
)

@bp.response(200, IncidentSchema(many=True))
Expand Down
45 changes: 20 additions & 25 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ def __repr__(self):

def as_string(self, attr_key):
return "<Component {}: {} ({})>".format(
self.id,
self.name,
self.get_attributes_as_dict()[attr_key]
self.id, self.name, self.get_attributes_as_dict()[attr_key]
)

@staticmethod
Expand Down Expand Up @@ -108,7 +106,7 @@ def all_with_active_incidents():
PropComparator.and_(
or_(
Incident.end_date.is_(None),
Incident.end_date > naive_utcnow()
Incident.end_date > naive_utcnow(),
),
Incident.start_date <= naive_utcnow(),
),
Expand All @@ -130,10 +128,9 @@ def count_components_by_attributes(attr_dict):
counter = 0
for comp in Component.all():
comp_attrs = comp.get_attributes_as_dict()
if set(
comp_attrs.items()
).intersection(set(
attr_dict.items())) == set(attr_dict.items()):
if set(comp_attrs.items()).intersection(
set(attr_dict.items())
) == set(attr_dict.items()):
counter += 1
return counter

Expand Down Expand Up @@ -174,15 +171,19 @@ def calculate_sla(self):
time_now = naive_utcnow()
this_month_start = datetime(time_now.year, time_now.month, 1)

outages = [inc for inc in self.incidents
if inc.impact == 3 and inc.end_date is not None]
outages = [
inc
for inc in self.incidents
if inc.impact == 3 and inc.end_date is not None
]
outages_dict = Incident.get_history_by_months(outages)
outages_dict_sorted = dict(sorted(outages_dict.items()))

prev_month_minutes = 0

months = [this_month_start + relativedelta(months=-mon)
for mon in range(6)]
months = [
this_month_start + relativedelta(months=-mon) for mon in range(6)
]
sla_dict = {month: 1 for month in months}

for month_start, outage_group in outages_dict_sorted.items():
Expand Down Expand Up @@ -272,12 +273,10 @@ class Incident(Base):
id = mapped_column(Integer, primary_key=True, index=True)
text: Mapped[str] = mapped_column(String())
start_date: Mapped[datetime] = mapped_column(
db.DateTime,
insert_default=naive_utcnow()
db.DateTime, insert_default=naive_utcnow()
)
end_date: Mapped[datetime] = mapped_column(nullable=True)
impact: Mapped[int] = mapped_column(db.SmallInteger)
# upgrade: system: Mapped[bool] = mapped_column(Boolean, default=False)
system: Mapped[bool] = mapped_column(Boolean, default=False)

components: Mapped[List["Component"]] = relationship(
Expand All @@ -299,7 +298,7 @@ def get_all_active():
select(Incident).filter(
or_(
Incident.end_date.is_(None),
Incident.end_date > naive_utcnow()
Incident.end_date > naive_utcnow(),
),
Incident.start_date <= naive_utcnow(),
)
Expand All @@ -311,7 +310,7 @@ def get_all_closed():
return db.session.scalars(
select(Incident).filter(
Incident.end_date.is_not(None),
Incident.end_date < naive_utcnow()
Incident.end_date < naive_utcnow(),
)
).all()

Expand All @@ -322,11 +321,8 @@ def get_history_by_months(incident_list):
incident_dict = {}
for incident in incident_list:
incident_dict.setdefault(
datetime(
incident.end_date.year,
incident.end_date.month,
1),
[]
datetime(incident.end_date.year, incident.end_date.month, 1),
[],
).append(incident)
return incident_dict

Expand All @@ -343,7 +339,7 @@ def get_active_maintenance():
# not closed
or_(
Incident.end_date.is_(None),
Incident.end_date > naive_utcnow()
Incident.end_date > naive_utcnow(),
),
Incident.impact == 0,
)
Expand Down Expand Up @@ -444,8 +440,7 @@ class IncidentStatus(Base):
incident_id = mapped_column(ForeignKey("incident.id"), index=True)
incident: Mapped["Incident"] = relationship(back_populates="updates")
timestamp: Mapped[datetime] = mapped_column(
db.DateTime,
insert_default=naive_utcnow()
db.DateTime, insert_default=naive_utcnow()
)
text: Mapped[str] = mapped_column(String())
status: Mapped[str] = mapped_column(String())

0 comments on commit 0d6a1fb

Please sign in to comment.