Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 2 additions & 4 deletions src/Frontend/src/components/AutoRefreshDataView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { onMounted, onUnmounted, ref, watch } from "vue";
import ItemsPerPage from "@/components/ItemsPerPage.vue";
import PaginationStrip from "@/components/PaginationStrip.vue";
import type DataViewPageModel from "./DataViewPageModel";
import { useServiceControlStore } from "@/stores/ServiceControlStore";
import serviceControlClient from "@/components/serviceControlClient";

const props = withDefaults(
defineProps<{
Expand All @@ -20,8 +20,6 @@ const props = withDefaults(
let refreshTimer: number | undefined;
const viewModel = defineModel<DataViewPageModel<T>>({ required: true });

const store = useServiceControlStore();

const pageNumber = ref(1);
const itemsPerPage = ref(props.itemsPerPage);

Expand All @@ -37,7 +35,7 @@ watch(itemsPerPage, () => loadData());
watch(pageNumber, () => loadData());

async function loadData() {
const [response, data] = await store.fetchTypedFromServiceControl<T[]>(`${props.apiUrl}?page=${pageNumber.value}&per_page=${itemsPerPage.value}`);
const [response, data] = await serviceControlClient.fetchTypedFromServiceControl<T[]>(`${props.apiUrl}?page=${pageNumber.value}&per_page=${itemsPerPage.value}`);
if (response.ok) {
viewModel.value.totalCount = parseInt(response.headers.get("Total-Count") ?? "0");
viewModel.value.data = data;
Expand Down
21 changes: 7 additions & 14 deletions src/Frontend/src/components/BackendChecksNotifications.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,15 @@ import { useShowToast } from "@/composables/toast";
import { TYPE } from "vue-toastification";
import useConnectionsAndStatsAutoRefresh from "@/composables/useConnectionsAndStatsAutoRefresh";
import useEnvironmentAndVersionsAutoRefresh from "@/composables/useEnvironmentAndVersionsAutoRefresh";
import { useServiceControlStore } from "@/stores/ServiceControlStore";
import { storeToRefs } from "pinia";
import { useMonitoringStore } from "@/stores/MonitoringStore";
import serviceControlClient from "@/components/serviceControlClient";
import monitoringClient from "./monitoring/monitoringClient";

const router = useRouter();

const { store: connectionStore } = useConnectionsAndStatsAutoRefresh();
const connectionState = connectionStore.connectionState;
const monitoringConnectionState = connectionStore.monitoringConnectionState;
const { store: environmentStore } = useEnvironmentAndVersionsAutoRefresh();
const environment = environmentStore.environment;
const serviceControlStore = useServiceControlStore();
const monitoringStore = useMonitoringStore();
const { serviceControlUrl } = storeToRefs(serviceControlStore);
const { monitoringUrl, isMonitoringDisabled } = storeToRefs(monitoringStore);

const primaryConnectionFailure = computed(() => connectionState.unableToConnect);
const monitoringConnectionFailure = computed(() => monitoringConnectionState.unableToConnect);

Expand All @@ -31,26 +24,26 @@ watch(primaryConnectionFailure, (newValue, oldValue) => {
if (newValue !== oldValue && !(oldValue === null && newValue === false)) {
const connectionUrl = router.resolve(routeLinks.configuration.connections.link).href;
if (newValue) {
useShowToast(TYPE.ERROR, "Error", `Could not connect to ServiceControl at ${serviceControlUrl.value}. <a class="btn btn-default" href="${connectionUrl}">View connection settings</a>`);
useShowToast(TYPE.ERROR, "Error", `Could not connect to ServiceControl at ${serviceControlClient.url}. <a class="btn btn-default" href="${connectionUrl}">View connection settings</a>`);
} else {
useShowToast(TYPE.SUCCESS, "Success", `Connection to ServiceControl was successful at ${serviceControlUrl.value}.`);
useShowToast(TYPE.SUCCESS, "Success", `Connection to ServiceControl was successful at ${serviceControlClient.url}.`);
}
}
});

watch(monitoringConnectionFailure, (newValue, oldValue) => {
// Only watch the state change if monitoring is enabled
if (isMonitoringDisabled.value) {
if (monitoringClient.isMonitoringDisabled) {
return;
}

//NOTE to eliminate success msg showing everytime the screen is refreshed
if (newValue !== oldValue && !(oldValue === null && newValue === false)) {
const connectionUrl = router.resolve(routeLinks.configuration.connections.link).href;
if (newValue) {
useShowToast(TYPE.ERROR, "Error", `Could not connect to the ServiceControl Monitoring service at ${monitoringUrl.value}. <a class="btn btn-default" href="${connectionUrl}">View connection settings</a>`);
useShowToast(TYPE.ERROR, "Error", `Could not connect to the ServiceControl Monitoring service at ${monitoringClient.url}. <a class="btn btn-default" href="${connectionUrl}">View connection settings</a>`);
} else {
useShowToast(TYPE.SUCCESS, "Success", `Connection to ServiceControl Monitoring service was successful at ${monitoringUrl.value}.`);
useShowToast(TYPE.SUCCESS, "Success", `Connection to ServiceControl Monitoring service was successful at ${monitoringClient.url}.`);
}
}
});
Expand Down
17 changes: 5 additions & 12 deletions src/Frontend/src/components/PageFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,28 @@ import FAIcon from "@/components/FAIcon.vue";
import { faArrowTurnUp, faPlus } from "@fortawesome/free-solid-svg-icons";
import useConnectionsAndStatsAutoRefresh from "@/composables/useConnectionsAndStatsAutoRefresh";
import useEnvironmentAndVersionsAutoRefresh from "@/composables/useEnvironmentAndVersionsAutoRefresh";
import { useServiceControlStore } from "@/stores/ServiceControlStore";
import serviceControlClient from "@/components/serviceControlClient";
import { storeToRefs } from "pinia";
import { useConfigurationStore } from "@/stores/ConfigurationStore";
import { useLicenseStore } from "@/stores/LicenseStore";
import { useMonitoringStore } from "@/stores/MonitoringStore";
import monitoringClient from "./monitoring/monitoringClient";

const { store: connectionStore } = useConnectionsAndStatsAutoRefresh();
const connectionState = connectionStore.connectionState;
const monitoringConnectionState = connectionStore.monitoringConnectionState;
const { store: environmentAndVersionsStore } = useEnvironmentAndVersionsAutoRefresh();
const newVersions = environmentAndVersionsStore.newVersions;
const environment = environmentAndVersionsStore.environment;
const serviceControlStore = useServiceControlStore();
const monitoringStore = useMonitoringStore();
const { serviceControlUrl } = storeToRefs(serviceControlStore);
const { monitoringUrl } = storeToRefs(monitoringStore);
const licenseStore = useLicenseStore();
const { licenseStatus, license } = licenseStore;

const isMonitoringEnabled = computed(() => {
return monitoringUrl.value !== "!" && monitoringUrl.value !== "" && monitoringUrl.value !== null && monitoringUrl.value !== undefined;
});
const isMonitoringEnabled = monitoringClient.isMonitoringEnabled;

const scAddressTooltip = computed(() => {
return `ServiceControl URL ${serviceControlUrl.value}`;
return `ServiceControl URL ${serviceControlClient.url}`;
});

const scMonitoringAddressTooltip = computed(() => {
return `Monitoring URL ${monitoringUrl.value}`;
return `Monitoring URL ${monitoringClient.url}`;
});

const configurationStore = useConfigurationStore();
Expand Down
8 changes: 3 additions & 5 deletions src/Frontend/src/components/PageHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ import DashboardMenuItem from "@/components/dashboard/DashboardMenuItem.vue";
import FeedbackButton from "@/components/FeedbackButton.vue";
import ThroughputMenuItem from "@/views/throughputreport/ThroughputMenuItem.vue";
import AuditMenuItem from "./audit/AuditMenuItem.vue";
import { useMonitoringStore } from "@/stores/MonitoringStore";
import { storeToRefs } from "pinia";
import monitoringClient from "@/components/monitoring/monitoringClient";

const monitoringStore = useMonitoringStore();
const { isMonitoringEnabled } = storeToRefs(monitoringStore);
const isMonitoringEnabled = monitoringClient.isMonitoringEnabled;
// prettier-ignore
const menuItems = computed(
() => [
DashboardMenuItem,
HeartbeatsMenuItem,
...(isMonitoringEnabled.value ? [MonitoringMenuItem] : []),
...(isMonitoringEnabled ? [MonitoringMenuItem] : []),
AuditMenuItem,
FailedMessagesMenuItem,
CustomChecksMenuItem,
Expand Down
7 changes: 2 additions & 5 deletions src/Frontend/src/components/ServiceControlAvailable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@
import ConditionalRender from "@/components/ConditionalRender.vue";
import routeLinks from "@/router/routeLinks";
import useConnectionsAndStatsAutoRefresh from "@/composables/useConnectionsAndStatsAutoRefresh";
import { useServiceControlStore } from "@/stores/ServiceControlStore";
import { storeToRefs } from "pinia";
import serviceControlClient from "@/components/serviceControlClient";

const { store: connectionStore } = useConnectionsAndStatsAutoRefresh();
const connectionState = connectionStore.connectionState;
const serviceControlStore = useServiceControlStore();
const { serviceControlUrl } = storeToRefs(serviceControlStore);
</script>

<template>
Expand All @@ -19,7 +16,7 @@ const { serviceControlUrl } = storeToRefs(serviceControlStore);
<h1>Cannot connect to ServiceControl</h1>
<p>
ServicePulse is unable to connect to the ServiceControl instance at
<span id="serviceControlUrl">{{ serviceControlUrl }}</span
<span id="serviceControlUrl">{{ serviceControlClient.url }}</span
>. Please ensure that ServiceControl is running and accessible from your machine.
</p>
<div class="action-toolbar">
Expand Down
43 changes: 4 additions & 39 deletions src/Frontend/src/components/configuration/EndpointConnection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,9 @@ import { onMounted, ref } from "vue";
import LicenseNotExpired from "../LicenseNotExpired.vue";
import ServiceControlAvailable from "../ServiceControlAvailable.vue";
import CodeEditor from "@/components/CodeEditor.vue";
import { useServiceControlStore } from "@/stores/ServiceControlStore";
import { storeToRefs } from "pinia";
import serviceControlClient, { ServiceControlInstanceConnection } from "@/components/serviceControlClient";
import LoadingSpinner from "../LoadingSpinner.vue";
import { useMonitoringStore } from "@/stores/MonitoringStore";

interface ServiceControlInstanceConnection {
settings: { [key: string]: object };
errors: string[];
}

interface MetricsConnectionDetails {
Enabled: boolean;
MetricsQueue?: string;
Interval?: string;
}

const serviceControlStore = useServiceControlStore();
const monitoringStore = useMonitoringStore();
const { serviceControlUrl } = storeToRefs(serviceControlStore);
const { monitoringUrl } = storeToRefs(monitoringStore);
import monitoringClient, { MetricsConnectionDetails } from "../monitoring/monitoringClient";

const loading = ref(true);
const showCodeOnlyTab = ref(true);
Expand Down Expand Up @@ -78,8 +61,8 @@ function switchJsonTab() {
}

async function serviceControlConnections() {
const scConnectionResult = getServiceControlConnection();
const monitoringConnectionResult = getMonitoringConnection();
const scConnectionResult = serviceControlClient.getServiceControlConnection();
const monitoringConnectionResult = monitoringClient.getMonitoringConnection();

const [scConnection, mConnection] = await Promise.all([scConnectionResult, monitoringConnectionResult]);
return {
Expand All @@ -93,24 +76,6 @@ async function serviceControlConnections() {
},
};
}

async function getServiceControlConnection() {
try {
const [, data] = await serviceControlStore.fetchTypedFromServiceControl<ServiceControlInstanceConnection>("connection");
return data;
} catch {
return { errors: [`Error reaching ServiceControl at ${serviceControlUrl.value} connection`] } as ServiceControlInstanceConnection;
}
}

async function getMonitoringConnection() {
try {
const [, data] = await monitoringStore.fetchTypedFromMonitoring<{ Metrics: MetricsConnectionDetails }>("connection");
return { ...data, errors: [] };
} catch {
return { Metrics: null, errors: [`Error SC Monitoring instance at ${monitoringUrl.value}connection`] };
}
}
</script>

<template>
Expand Down
28 changes: 9 additions & 19 deletions src/Frontend/src/components/configuration/PlatformConnections.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,21 @@ import { ref } from "vue";
import { faCheck, faExclamationTriangle } from "@fortawesome/free-solid-svg-icons";
import FAIcon from "@/components/FAIcon.vue";
import useConnectionsAndStatsAutoRefresh from "@/composables/useConnectionsAndStatsAutoRefresh";
import { useServiceControlStore } from "@/stores/ServiceControlStore";
import { storeToRefs } from "pinia";
import { useMonitoringStore } from "@/stores/MonitoringStore";
import serviceControlClient from "@/components/serviceControlClient";
import monitoringClient from "../monitoring/monitoringClient";

const { store: connectionStore } = useConnectionsAndStatsAutoRefresh();
const connectionState = connectionStore.connectionState;
const monitoringConnectionState = connectionStore.monitoringConnectionState;

const serviceControlStore = useServiceControlStore();
const monitoringStore = useMonitoringStore();
serviceControlStore.refresh();
monitoringStore.refresh();
const localServiceControlUrl = ref(serviceControlStore.serviceControlUrl);
const localMonitoringUrl = ref(monitoringStore.monitoringUrl);
const { isMonitoringDisabled } = storeToRefs(monitoringStore);

const localServiceControlUrl = ref(serviceControlClient.url);
const localMonitoringUrl = ref(monitoringClient.url);
const isMonitoringDisabled = monitoringClient.isMonitoringDisabled;
const testingServiceControl = ref(false);
const serviceControlValid = ref<boolean | null>(null);

const testingMonitoring = ref(false);
const monitoringValid = ref<boolean | null>(null);

const connectionSaved = ref<boolean | null>(null);

async function testServiceControlUrl() {
Expand Down Expand Up @@ -82,13 +75,10 @@ function updateServiceControlUrls() {
localMonitoringUrl.value += "/";
}

//values have changed. They'll be reset after page reloads
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my understanding is that these values are used in determining the url that's actually used in the SC and monitoring clients, so wouldn't this logic still be necessary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is now handled in the client getUrl?

const existingScu = window.localStorage.getItem("scu");

    if (scu) {
      if (scu !== existingScu) {
        window.localStorage.setItem("scu", scu);
      }
      return scu;
    }

window.localStorage.removeItem("scu");
window.localStorage.removeItem("mu");

const newSearch = `?scu=${localServiceControlUrl.value}&mu=${localMonitoringUrl.value}`;
console.debug("updateConnections - new query string: ", newSearch);
window.location.search = newSearch;
const params = new URLSearchParams();
params.set("scu", localServiceControlUrl.value);
params.set("mu", localMonitoringUrl.value);
window.location.search = `?${params.toString()}`;
}
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import SortOptions, { SortDirection } from "@/resources/SortOptions";
import GroupOperation from "@/resources/GroupOperation";
import getSortFunction from "@/components/getSortFunction";
import { faArrowDownAZ, faArrowDownZA, faArrowDownShortWide, faArrowDownWideShort, faArrowDown19, faArrowDown91 } from "@fortawesome/free-solid-svg-icons";
import { useServiceControlStore } from "@/stores/ServiceControlStore";

const serviceControlStore = useServiceControlStore();
import serviceControlClient from "@/components/serviceControlClient";

const selectedClassifier = ref<string>("");
const classifiers = ref<string[]>([]);
Expand Down Expand Up @@ -60,7 +58,7 @@ const sortOptions: SortOptions<GroupOperation>[] = [
];

async function getGroupingClassifiers() {
const [, data] = await serviceControlStore.fetchTypedFromServiceControl<string[]>("recoverability/classifiers");
const [, data] = await serviceControlClient.fetchTypedFromServiceControl<string[]>("recoverability/classifiers");
classifiers.value = data;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ import RecoverabilityHistoryResponse from "@/resources/RecoverabilityHistoryResp
import FAIcon from "@/components/FAIcon.vue";
import { faAngleDown, faAngleRight, faEnvelope } from "@fortawesome/free-solid-svg-icons";
import { faClock } from "@fortawesome/free-regular-svg-icons";
import { useServiceControlStore } from "@/stores/ServiceControlStore";
import serviceControlClient from "@/components/serviceControlClient";

const historicOperations = ref<HistoricRetryOperation[]>([]);
const showHistoricRetries = ref(false);

const serviceControlStore = useServiceControlStore();

async function getHistoricOperations() {
const [, data] = await serviceControlStore.fetchTypedFromServiceControl<RecoverabilityHistoryResponse>("recoverability/history");
const [, data] = await serviceControlClient.fetchTypedFromServiceControl<RecoverabilityHistoryResponse>("recoverability/history");
historicOperations.value = data.historic_operations;
}

Expand Down
24 changes: 9 additions & 15 deletions src/Frontend/src/components/failedmessages/messageGroupClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ServiceControlStore, useServiceControlStore } from "@/stores/ServiceControlStore";
import serviceControlClient from "@/components/serviceControlClient";
import type GroupOperation from "@/resources/GroupOperation";

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
Expand All @@ -8,52 +8,46 @@ export interface ErrorResponse {
}

export class MessageGroupClient {
serviceControlStore: ServiceControlStore;
constructor() {
//this module is only called from within view setup or other pinia stores, so this call is lifecycle safe
this.serviceControlStore = useServiceControlStore();
}

public async getExceptionGroups(classifier: string = "") {
const [, data] = await this.serviceControlStore.fetchTypedFromServiceControl<GroupOperation[]>(`recoverability/groups/${classifier}`);
const [, data] = await serviceControlClient.fetchTypedFromServiceControl<GroupOperation[]>(`recoverability/groups/${classifier}`);
return data;
}

public async getExceptionGroupsForEndpoint(classifier: string = "", classiferFilter = "") {
const [, data] = await this.serviceControlStore.fetchTypedFromServiceControl<GroupOperation[]>(`recoverability/groups/${classifier}?classifierFilter=${classiferFilter}`);
const [, data] = await serviceControlClient.fetchTypedFromServiceControl<GroupOperation[]>(`recoverability/groups/${classifier}?classifierFilter=${classiferFilter}`);
return data;
}

//delete note by group id
public async deleteNote(groupId: string) {
return this.evaluateResponse(await this.serviceControlStore.deleteFromServiceControl(`recoverability/groups/${groupId}/comment`));
return this.evaluateResponse(await serviceControlClient.deleteFromServiceControl(`recoverability/groups/${groupId}/comment`));
}

//edit or create note by group id
public async editOrCreateNote(groupId: string, comment: string) {
return this.evaluateResponse(await this.serviceControlStore.postToServiceControl(`recoverability/groups/${groupId}/comment?comment=${comment}`));
return this.evaluateResponse(await serviceControlClient.postToServiceControl(`recoverability/groups/${groupId}/comment?comment=${comment}`));
}

//archive exception group by group id
//archiveGroup
public async archiveExceptionGroup(groupId: string) {
return this.evaluateResponse(await this.serviceControlStore.postToServiceControl(`recoverability/groups/${groupId}/errors/archive`));
return this.evaluateResponse(await serviceControlClient.postToServiceControl(`recoverability/groups/${groupId}/errors/archive`));
}

//restore group by group id
public async restoreGroup(groupId: string) {
return this.evaluateResponse(await this.serviceControlStore.postToServiceControl(`recoverability/groups/${groupId}/errors/unarchive`));
return this.evaluateResponse(await serviceControlClient.postToServiceControl(`recoverability/groups/${groupId}/errors/unarchive`));
}

//retry exception group by group id
//retryGroup
public async retryExceptionGroup(groupId: string) {
return this.evaluateResponse(await this.serviceControlStore.postToServiceControl(`recoverability/groups/${groupId}/errors/retry`));
return this.evaluateResponse(await serviceControlClient.postToServiceControl(`recoverability/groups/${groupId}/errors/retry`));
}

//acknowledge archive exception group by group id
public async acknowledgeArchiveGroup(groupId: string) {
return this.evaluateResponse(await this.serviceControlStore.deleteFromServiceControl(`recoverability/unacknowledgedgroups/${groupId}`));
return this.evaluateResponse(await serviceControlClient.deleteFromServiceControl(`recoverability/unacknowledgedgroups/${groupId}`));
}

evaluateResponse(response: Response): SuccessResponse | ErrorResponse {
Expand Down
Loading