diff --git a/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config b/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config
index cfb7d8c..01bb731 100644
--- a/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config
+++ b/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config
@@ -9,6 +9,7 @@
+
diff --git a/F4SDM42WebApi/F4SD - M42WebApi.csproj b/F4SDM42WebApi/F4SD - M42WebApi.csproj
index e836f90..88aaaa6 100644
--- a/F4SDM42WebApi/F4SD - M42WebApi.csproj
+++ b/F4SDM42WebApi/F4SD - M42WebApi.csproj
@@ -13,7 +13,7 @@
false
6673a25d-33d6-4072-91d9-abed4be1a966
C4ITF4SD*.*
- 1.4.0.31
+ 1.4.0.32
true
@@ -34,10 +34,6 @@
M42Libraries\26.1\Matrix42.Contracts.ServiceManagement.dll
false
-
- M42Libraries\26.1\Matrix42.BizLogic.Journal.dll
- false
-
M42Libraries\26.1\Matrix42.Hosting.Contracts.dll
false
diff --git a/F4SDM42WebApi/F4SDHelperService.cs b/F4SDM42WebApi/F4SDHelperService.cs
index 1c84ee2..617dbee 100644
--- a/F4SDM42WebApi/F4SDHelperService.cs
+++ b/F4SDM42WebApi/F4SDHelperService.cs
@@ -1,7 +1,6 @@
using C4IT.F4SDM;
using C4IT.FASD.Base;
using C4IT.Logging;
-using Matrix42.BizLogic.Common.Journal;
using Matrix42.Common;
using Newtonsoft.Json;
using System;
@@ -1455,7 +1454,7 @@ namespace C4IT.F4SD
private static IReadOnlyList LoadJournalEntries(Guid activityEOID)
{
- var journalService = F4SDM42WebApiController.defaultInstance.GetJournalServiceInstance();
+ var journalService = F4SDM42WebApiController.defaultInstance.GetJournalService();
var serviceType = journalService.GetType();
var objectLinkTemplate = "{2}";
var methods = serviceType
@@ -1482,12 +1481,6 @@ namespace C4IT.F4SD
}
catch (TargetInvocationException ex) when (ex.InnerException != null)
{
- if (IsStorageWebApiExplorerResolutionFailure(ex.InnerException))
- {
- LogEntry("JournalService.GetJournalList requires IStorageService in this Matrix42 build. Falling back to JournalManager.GetObjectEntries for sandbox compatibility.", LogLevels.Warning);
- return LoadJournalEntriesFromJournalManager(activityEOID, objectLinkTemplate);
- }
-
throw ex.InnerException;
}
}
@@ -1495,38 +1488,6 @@ namespace C4IT.F4SD
throw new MissingMethodException($"No compatible IJournalService.GetJournalList overload was found on '{serviceType.FullName}'. Available overloads: {string.Join("; ", methods.Select(FormatMethodSignature))}");
}
- private static IReadOnlyList LoadJournalEntriesFromJournalManager(Guid activityEOID, string objectLinkTemplate)
- {
- var entries = JournalManager.GetObjectEntries(
- activityEOID,
- false,
- null,
- 0,
- 50,
- false,
- objectLinkTemplate,
- 120);
-
- return entries
- .Select(item => new Matrix42.Contracts.Platform.Data.JournalEntryInfo
- {
- Id = item.Id,
- Creator = item.CreatorName,
- CreatedDate = item.CreatedDate,
- Header = item.Header,
- Text = item.Body ?? string.Empty,
- VisibleInPortal = item.VisibleInPortal
- })
- .ToList();
- }
-
- private static bool IsStorageWebApiExplorerResolutionFailure(Exception exception)
- {
- var details = exception.ToString();
- return details.Contains("Matrix42.StorageService.Contracts.IStorageService")
- && details.Contains("System.Web.Http.Description.IApiExplorer");
- }
-
private static bool IsJournalReaderMethod(MethodInfo method)
{
var methodName = method.Name;
diff --git a/F4SDM42WebApi/F4SDM42WebApiController.cs b/F4SDM42WebApi/F4SDM42WebApiController.cs
index b48d35d..f78f88b 100644
--- a/F4SDM42WebApi/F4SDM42WebApiController.cs
+++ b/F4SDM42WebApi/F4SDM42WebApiController.cs
@@ -43,12 +43,6 @@ namespace C4IT.F4SD
private readonly F4SDHelperService _f4stHelperService;
- private const string TeamsNotificationServiceTypeName = "Matrix42.Contracts.Platform.MsTeams.ITeamsNotificationService";
- private const string StorageServiceTypeName = "Matrix42.StorageService.Contracts.IStorageService";
- private const int JournalStart = 0;
- private const int JournalCount = 50;
- private const int JournalTimeOffset = 120;
- private const string JournalObjectLinkTemplate = "{2}";
public string BaseUrl => Request?.RequestUri == null ? string.Empty : $"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}";
public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi";
@@ -102,165 +96,6 @@ namespace C4IT.F4SD
return GetRequiredService();
}
- internal object GetJournalServiceInstance()
- {
- try
- {
- return GetRequiredService();
- }
- catch (Exception ex)
- {
- LogEntry($"IJournalService could not be resolved by the Matrix42 container. Falling back to direct JournalService construction. {ex.GetType().FullName}: {ex.Message}", LogLevels.Warning);
- return CreateJournalServiceInstance();
- }
- }
-
- private object CreateJournalServiceInstance()
- {
- var journalServiceType = FindLoadedType("Matrix42.ServiceManager.BizLogic.Services.JournalService")
- ?? Type.GetType("Matrix42.ServiceManager.BizLogic.Services.JournalService, Matrix42.ServiceManager.BizLogic", true);
- var constructor = journalServiceType
- .GetConstructors()
- .OrderByDescending(item => item.GetParameters().Length)
- .FirstOrDefault();
-
- if (constructor == null)
- throw new InvalidOperationException($"No public constructor was found for {journalServiceType.FullName}.");
-
- var parameters = constructor.GetParameters();
- var arguments = new object[parameters.Length];
- for (int i = 0; i < parameters.Length; i++)
- arguments[i] = ResolveJournalServiceConstructorParameter(parameters[i]);
-
- return constructor.Invoke(arguments);
- }
-
- private object ResolveJournalServiceConstructorParameter(System.Reflection.ParameterInfo parameter)
- {
- if (parameter.ParameterType == typeof(IDependencyResolver))
- return CreateJournalDependencyResolver(_resolver);
-
- if (parameter.ParameterType.FullName == TeamsNotificationServiceTypeName || parameter.ParameterType.FullName == StorageServiceTypeName)
- return CreateNoOpInterfaceProxy(parameter.ParameterType);
-
- var service = _resolver.TryGet(parameter.ParameterType);
- if (service != null)
- return service;
-
- throw new InvalidOperationException($"Required JournalService constructor dependency is not registered: {parameter.ParameterType.FullName} ({parameter.Name}).");
- }
-
- private static IDependencyResolver CreateJournalDependencyResolver(IDependencyResolver resolver)
- {
- var proxy = DispatchProxy.Create();
- ((JournalDependencyResolverProxy)(object)proxy).Inner = resolver;
- return proxy;
- }
-
- private static Type FindLoadedType(string fullName)
- {
- return AppDomain.CurrentDomain
- .GetAssemblies()
- .Select(assembly => assembly.GetType(fullName, false))
- .FirstOrDefault(type => type != null);
- }
-
- private static object CreateNoOpInterfaceProxy(Type interfaceType)
- {
- var createMethod = typeof(DispatchProxy)
- .GetMethods(BindingFlags.Public | BindingFlags.Static)
- .Single(method => method.Name == nameof(DispatchProxy.Create) && method.IsGenericMethodDefinition);
-
- return createMethod
- .MakeGenericMethod(interfaceType, typeof(NoOpInterfaceProxy))
- .Invoke(null, null);
- }
-
- public class JournalDependencyResolverProxy : DispatchProxy
- {
- public IDependencyResolver Inner { get; set; }
-
- protected override object Invoke(MethodInfo targetMethod, object[] args)
- {
- var requestedType = GetRequestedServiceType(targetMethod, args);
- if (requestedType?.FullName == StorageServiceTypeName)
- return CreateResolverResultForStorageService(targetMethod, requestedType);
-
- try
- {
- return targetMethod.Invoke(Inner, args);
- }
- catch (TargetInvocationException ex) when (ex.InnerException != null)
- {
- throw ex.InnerException;
- }
- }
- }
-
- private static Type GetRequestedServiceType(MethodInfo targetMethod, object[] args)
- {
- if (targetMethod.IsGenericMethod && targetMethod.GetGenericArguments().Length > 0)
- return targetMethod.GetGenericArguments()[0];
-
- if (args?.Length > 0 && args[0] is Type type)
- return type;
-
- return null;
- }
-
- private static object CreateResolverResultForStorageService(MethodInfo targetMethod, Type requestedType)
- {
- if (targetMethod.Name.StartsWith("IsRegistered", StringComparison.Ordinal))
- return true;
-
- if (targetMethod.Name.Contains("All"))
- return CreateEmptyEnumerable(targetMethod.ReturnType, requestedType);
-
- return CreateNoOpInterfaceProxy(requestedType);
- }
-
- private static object CreateEmptyEnumerable(Type returnType, Type itemType)
- {
- if (returnType.IsGenericType)
- return Array.CreateInstance(returnType.GetGenericArguments()[0], 0);
-
- return Array.CreateInstance(itemType ?? typeof(object), 0);
- }
-
- public class NoOpInterfaceProxy : DispatchProxy
- {
- public NoOpInterfaceProxy()
- {
- }
-
- protected override object Invoke(MethodInfo targetMethod, object[] args)
- {
- return GetDefaultValue(targetMethod?.ReturnType);
- }
- }
-
- private static object GetDefaultValue(Type returnType)
- {
- if (returnType == null || returnType == typeof(void))
- return null;
-
- if (returnType == typeof(Task))
- return Task.CompletedTask;
-
- if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
- {
- var resultType = returnType.GetGenericArguments()[0];
- var result = resultType.IsValueType ? Activator.CreateInstance(resultType) : null;
- return typeof(Task)
- .GetMethods(BindingFlags.Public | BindingFlags.Static)
- .Single(method => method.Name == nameof(Task.FromResult) && method.IsGenericMethodDefinition)
- .MakeGenericMethod(resultType)
- .Invoke(null, new[] { result });
- }
-
- return returnType.IsValueType ? Activator.CreateInstance(returnType) : null;
- }
-
[Route("getDirectLinkCreateTicket"), HttpGet]
public async Task getDirectLinkCreateTicket(string sid = "", string assetname = "")
{
@@ -308,13 +143,6 @@ namespace C4IT.F4SD
{
try
{
- var journalPortalEntries = await TryGetJournalPortalEntries(objectId);
- if (journalPortalEntries != null)
- {
- LogEntry($"{journalPortalEntries.Count} Journal entries loaded from Matrix42 JournalPortalController for ObjectID={objectId}", LogLevels.Debug);
- return F4SDHelperService.CreateTicketJournalItems(objectId, journalPortalEntries);
- }
-
return await _f4stHelperService.GetJournalEntries(objectId);
}
catch (MissingMethodException ex)
@@ -323,90 +151,6 @@ namespace C4IT.F4SD
}
}
- private async Task> TryGetJournalPortalEntries(Guid objectId)
- {
- if (Request?.RequestUri == null)
- return null;
-
- foreach (var requestUri in BuildJournalPortalUris(objectId))
- {
- try
- {
- using (var handler = new HttpClientHandler { UseDefaultCredentials = true, AutomaticDecompression = DecompressionMethods.All })
- using (var client = new HttpClient(handler))
- using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
- {
- client.Timeout = TimeSpan.FromSeconds(15);
- CopyIncomingHeaders(request);
- using (var response = await client.SendAsync(request))
- {
- var responseText = await response.Content.ReadAsStringAsync();
- if (!response.IsSuccessStatusCode)
- {
- LogEntry($"Matrix42 JournalPortalController returned {(int)response.StatusCode} {response.ReasonPhrase} for {requestUri}. {responseText}", LogLevels.Warning);
- continue;
- }
-
- var entries = DeserializeJournalPortalEntries(responseText);
- if (entries != null)
- return entries;
-
- LogEntry($"Matrix42 JournalPortalController response could not be deserialized for {requestUri}. {responseText}", LogLevels.Warning);
- }
- }
- }
- catch (Exception ex)
- {
- LogEntry($"Matrix42 JournalPortalController request failed for {requestUri}. {ex.GetType().FullName}: {ex.Message}", LogLevels.Warning);
- }
- }
-
- return null;
- }
-
- private IEnumerable BuildJournalPortalUris(Guid objectId)
- {
- var query = $"objectId={Uri.EscapeDataString(objectId.ToString())}&start={JournalStart}&count={JournalCount}&objectLinkTemplate={Uri.EscapeDataString(JournalObjectLinkTemplate)}&timeOffset={JournalTimeOffset}";
- yield return new Uri($"{BaseUrl}/m42Services/api/journalPortal?{query}");
- yield return new Uri($"{BaseUrl}/api/journalPortal?{query}");
- }
-
- private void CopyIncomingHeaders(HttpRequestMessage request)
- {
- foreach (var header in Request.Headers)
- {
- if (string.Equals(header.Key, "Host", StringComparison.OrdinalIgnoreCase)
- || string.Equals(header.Key, "Connection", StringComparison.OrdinalIgnoreCase)
- || string.Equals(header.Key, "Accept-Encoding", StringComparison.OrdinalIgnoreCase))
- continue;
-
- request.Headers.TryAddWithoutValidation(header.Key, header.Value);
- }
- }
-
- private static Matrix42.Contracts.Platform.Data.JournalEntryInfo[] DeserializeJournalPortalEntries(string responseText)
- {
- try
- {
- return Newtonsoft.Json.JsonConvert.DeserializeObject(responseText);
- }
- catch
- {
- var token = Newtonsoft.Json.Linq.JToken.Parse(responseText);
- if (token.Type == Newtonsoft.Json.Linq.JTokenType.Array)
- return token.ToObject();
-
- foreach (var propertyName in new[] { "result", "Result", "value", "Value" })
- {
- var resultToken = token[propertyName];
- if (resultToken != null && resultToken.Type != Newtonsoft.Json.Linq.JTokenType.Null)
- return resultToken.ToObject();
- }
-
- return null;
- }
- }
-
internal static List CreateMissingMethodDiagnostics(string stage, Guid objectId, MissingMethodException ex)
{
var details = BuildMissingMethodDiagnostic(stage, objectId, ex);