/// <summary> /// fill the file mapping when passed through the cache: placed into the cache by the runtime-engine, passed /// as '<fileurl val = "/..."' /// </summary> /// <param name = "TAG_URL"></param> internal void FillFromUrl(String tagName) { XmlParser parser = ClientManager.Instance.RuntimeCtx.Parser; String XMLdata = parser.getXMLdata(); int endContext = parser.getXMLdata().IndexOf(XMLConstants.TAG_TERM, parser.getCurrIndex()); if (endContext != -1 && endContext < XMLdata.Length) { // find last position of its tag String tagAndAttributes = parser.getXMLsubstring(endContext); parser.add2CurrIndex(tagAndAttributes.IndexOf(tagName) + tagName.Length); List <String> tokensVector = XmlParser.getTokens(parser.getXMLsubstring(endContext), XMLConstants.XML_ATTR_DELIM); Debug.Assert((tokensVector[0]).Equals(XMLConstants.MG_ATTR_VALUE)); String cachedTaskDefinitionIdsUrl = (tokensVector[1]); byte[] content = ApplicationSourcesManager.GetInstance().ReadSource(cachedTaskDefinitionIdsUrl, true); if (tagName.Equals(ConstInterface.MG_TAG_TASKDEFINITION_IDS_URL)) { ClientManager.Instance.LocalManager.ApplicationDefinitions.TaskDefinitionIdsManager.FillFrom(content); } endContext = XMLdata.IndexOf(XMLConstants.TAG_OPEN, endContext); if (endContext != -1) { parser.setCurrIndex(endContext); } } }
/// <summary> /// commit changes that made to data sources /// </summary> internal void Commit() { SourcesSyncStatus sourcesSyncStatus = ApplicationSourcesManager.GetInstance().SourcesSyncStatus; if (_convertCommandList.Count > 0) { // It is about to start committing the tables. So save the status. If process get terminated during commit, // in next execution, client will get to know the status of data sources synchronization and take action accordingly. // This flag will be set to false after commiting sources successfully. sourcesSyncStatus.TablesIncompatibleWithDataSources = true; sourcesSyncStatus.SaveToFile(); } try { foreach (IConvertCommand command in _convertCommandList) { command.Execute(); } } catch (Exception e) { String errorMessage = ClientManager.Instance.getMessageString(MsgInterface.RC_ERROR_INCOMPATIBLE_DATASOURCES); throw new InvalidSourcesException(errorMessage, e); } }
/// <summary> /// Starts session locally without trying to connect to server. /// </summary> private static bool StartSessionLocally() { bool succeeded = false; // Enable offline required metadata collection which is needed to verify client cache, // during connecting to server (switching to connected mode for first server operation) ApplicationSourcesManager.GetInstance().OfflineRequiredMetadataCollection.Enabled = true; // switch session status from "Uninitialized" to "Local" ClientManager.Instance.GetService <IConnectionStateManager>().ConnectionDropped(); Logger.Instance.WriteServerToLog("Attempting to start locally (Offline mode)"); succeeded = LocalCommandsProcessor.GetInstance().StartSession(); if (succeeded) { // Set server last access status RemoteCommandsProcessor.GetInstance().ServerLastAccessStatus = ServerAccessStatus.SkippedConnectionToServer; } else { Logger.Instance.WriteServerToLog("Cannot start locally. Terminating client."); } if (Logger.Instance.IsAccumulatingMessages()) { Logger.Instance.FlushAccumulatedMessages(); } // No cache files should be collected once the session is started. ApplicationSourcesManager.GetInstance().OfflineRequiredMetadataCollection.Enabled = false; return(succeeded); }
/// <summary> /// add task definition id /// </summary> /// <param name="taskDefinitionId"></param> /// <param name="xmlId"></param> /// <param name="defaultTagList"></param> /// <param name="executionRightIdx"></param> internal void AddTaskDefinitionId(TaskDefinitionId taskDefinitionId, string xmlId, string defaultTagList, int executionRightIdx) { lock (_TaskDefinitionIdsCache) { TaskDefinitionIdInfo taskDefinitionIdInfo = new TaskDefinitionIdInfo(xmlId, defaultTagList, executionRightIdx); _TaskDefinitionIdsCache.Add(taskDefinitionId, taskDefinitionIdInfo); // get the task's file from server to client ApplicationSourcesManager.GetInstance().ReadSource(xmlId, false, false); } }
/// <summary> /// Builds data repository from sources and handle conversion of data sources /// </summary> private void GetDataSourceDefinitions() { // read new sources from remote byte[] buf = ApplicationSourcesManager.GetInstance().ReadSource(dataDefinitionIdsUrl, true); this.DataSourceBuilder.DataSourceReader = GetDataSourceBuffer; new DataSourceDefinitionManagerSaxHandler(buf, this); if (CommandsProcessorManager.SessionStatus == CommandsProcessorManager.SessionStatusEnum.Remote) { // handle data source conversion if modified definition have any change related to database DataSourceConverter dataSourceConverter = ClientManager.Instance.LocalManager.DataSourceConverter = new DataSourceConverter(); dataSourceConverter.NewDataSourceRepositoryContents = buf; dataSourceConverter.HandleRepositoryChanges(this, dataDefinitionIdsUrl); } }
public void endElement(String elementName, String elementValue, NameValueCollection attributes) { if (elementName.Equals(XMLConstants.MG_TAG_ASSEMBLY)) { String path = attributes[XMLConstants.MG_ATTR_ASSEMBLY_PATH]; String isGuiThreadExecutionStr = attributes[XMLConstants.MG_ATTR_IS_GUI_THREAD_EXECUTION]; bool isGuiThreadExecution = isGuiThreadExecutionStr != null && isGuiThreadExecutionStr.Equals("1", StringComparison.CurrentCultureIgnoreCase); path = XmlParser.unescape(path); // Add assembly to the collection ReflectionServices.AddAssembly(path, false, path, isGuiThreadExecution); String strEncrypted = "&ENCRYPTED=N"; path = path.Remove(path.Length - strEncrypted.Length, strEncrypted.Length); ApplicationSourcesManager.GetInstance().ReadSource(path, false); } }
/// <summary> Initializes the Cache manager by proving it the required details from /// execution properties like, whether the encryption is on/off and the encryption key. </summary> /// <returns></returns> internal override bool StartSession() { // Sources integrity is needed when client STARTS in connected mode (Initialization phase in Remote session). // Not applicable in Local session, even after establishing connection with server to execute server operation. ApplicationSourcesManager.GetInstance().DisableSourceIntegrity(); // Verify that the last initial response file saved on the client for offline execution is valid: VerifyLastOfflineInitialResponseFile(); // Recheck if last offline response file still exists. It might have been deleted from VerifyInitialResponseProgramName bool canStartWithoutNetwork = CanStartWithoutNetwork; if (canStartWithoutNetwork) { ClientManager.Instance.ShouldScrambleAndUnscrambleMessages = GetShouldSecureMessages(); ExecuteInitialRequest(); } return(canStartWithoutNetwork); }
/// <summary> Loads the first response for executing the first program from the local file. </summary> private void ExecuteInitialRequest() { // Before starting the execution, check if any failure was occurred during updating the local data in last execution SourcesSyncStatus sourcesSyncStatus = ApplicationSourcesManager.GetInstance().SourcesSyncStatus; if (sourcesSyncStatus.TablesIncompatibleWithDataSources == true) { // structures of tables in local database does not match with their sources String errorMessage = ClientManager.Instance.getMessageString(MsgInterface.RC_ERROR_INCOMPATIBLE_DATASOURCES); throw new InvalidSourcesException(errorMessage, null); } else if (sourcesSyncStatus.InvalidSources == true) { // sources are not synchronized String errorMessage = ClientManager.Instance.getMessageString(MsgInterface.RC_ERROR_OFFLINE_NEXT_EXECUTION_INVALID_SOURCES); throw new InvalidSourcesException(errorMessage, null); } String initialResponseString = GetLastOfflineInitialResponse(); FlowMonitorQueue.Instance.enable(false); ClientManager.Instance.ProcessResponse(initialResponseString, 0, new OpeningTaskDetails(), null); }
/// <summary> /// Start session (Remote/Local) /// </summary> /// <returns></returns> internal static bool StartSession() { bool succeeded = false; bool startInConnectedModeToSyncMetadata = false; bool skipConnectionToServer = false; using (Logger.Instance.AccumulateMessages()) { // Check if client is required to start in disconnected mode even when network is available // Skip connection if, // 1. ConnectOnStartup = N in execution properties // 2. LastOffline does not contain "UnsyncronizedMetadata=Y" [which means connect server to sync metadata]. if (LocalCommandsProcessor.GetInstance().CanStartWithoutNetwork&& !ClientManager.Instance.GetConnectOnStartup()) { LocalCommandsProcessor.GetInstance().VerifyLastOfflineInitialResponseFile(); if (LocalCommandsProcessor.GetInstance().CanStartWithoutNetwork) { if (LocalCommandsProcessor.GetInstance().IsUnsyncronizedMetadata()) { startInConnectedModeToSyncMetadata = true; } else { skipConnectionToServer = true; } } } // Create a communications failure handler and pass it to the Http connection layer. HttpManager.GetInstance().SetCommunicationsFailureHandler( LocalCommandsProcessor.GetInstance().CanStartWithoutNetwork ? (ICommunicationsFailureHandler)(new SilentCommunicationsFailureHandler()) : (ICommunicationsFailureHandler)(new InteractiveCommunicationsFailureHandler())); if (skipConnectionToServer) { succeeded = StartSessionLocally(); } else { try { ApplicationSourcesManager.GetInstance().OfflineRequiredMetadataCollection.Enabled = true; // access the Server: if accessed - continue remotely, otherwise - locally. succeeded = RemoteCommandsProcessor.GetInstance().StartSession(); // Notify the Connection State Manager that a successful connection was established. // The first time this happens, the connection state manager will move from 'Unknown' to 'Connected'. ClientManager.Instance.GetService <IConnectionStateManager>().ConnectionEstablished(); } catch (Exception ex) { if (ex is InvalidSourcesException) { throw; } // If client started in connected mode (even when ConnectOnStartup=N in execution properties) because, // UnsyncronisedMetadata was occurred in last execution, and if any sever error occurred during initialization then, // ServerLastAccessStatus() should return 1 (UnsynchroizedMetadata). This way client will avoid trying any server operation. if (startInConnectedModeToSyncMetadata) { RemoteCommandsProcessor.GetInstance().ServerLastAccessStatus = ServerAccessStatus.UnsynchroizedMetadata; } Logger.Instance.WriteServerToLog("Failed connecting to the server: " + ex.Message); if (LocalCommandsProcessor.GetInstance().CanStartWithoutNetwork) { if (Logger.Instance.ShouldLog()) { Logger.Instance.FlushAccumulatedMessages(); } else { Logger.Instance.DiscardAccumulatedMessages(); } Logger.Instance.StopMessageAccumulation(); Logger.Instance.WriteServerToLog("Attempting to start locally (Offline mode)"); succeeded = LocalCommandsProcessor.GetInstance().StartSession(); } if (!succeeded) { Logger.Instance.WriteServerToLog("Cannot start locally. Terminating client."); throw; } } finally { if (Logger.Instance.IsAccumulatingMessages()) { Logger.Instance.FlushAccumulatedMessages(); } // all offline required cache files are retrieved when the server is started, in the initial response after the two handshake requests. // therefore, no cache files should be collected once the session is started [i.e. StartSession() was executed]. ApplicationSourcesManager.GetInstance().OfflineRequiredMetadataCollection.Enabled = false; } } } // if a startupProgram should be started locally then load it locally. if (GetCommandsProcessor().ShouldLoadOfflineStartupProgram()) { LocalCommandsProcessor.GetInstance().LoadStartupProgram(); } // From this point onward, all comm failures should show a message. HttpManager.GetInstance().SetCommunicationsFailureHandler(new InteractiveCommunicationsFailureHandler()); return(succeeded); }
/// <summary> /// get DataSource file from the server and parse it /// </summary> void GetDatabaseDefinitions() { byte[] buf = ApplicationSourcesManager.GetInstance().ReadSource(databaseDefinitionsUrl, true); new DatabaseDefinitionsSaxParser(buf, this); }
/// <summary> /// Reads contents of a datasource indicated by sourceUrl using ApplicationSourcesManager /// </summary> /// <param name="sourceUrl"></param> /// <returns></returns> private byte[] GetDataSourceBuffer(String sourceUrl) { return(ApplicationSourcesManager.GetInstance().ReadSource(sourceUrl, true)); }
/// <summary> /// fill the file mapping when passed through the cache: placed into the cache by the runtime-engine, passed /// as '<fileurl val = "/..."' /// </summary> /// <param name = "TAG_URL"></param> internal void fillFromUrl(String tagName) { XmlParser parser = ClientManager.Instance.RuntimeCtx.Parser; String XMLdata = parser.getXMLdata(); int endContext = parser.getXMLdata().IndexOf(XMLConstants.TAG_TERM, parser.getCurrIndex()); if (endContext != -1 && endContext < XMLdata.Length) { // find last position of its tag String tagAndAttributes = parser.getXMLsubstring(endContext); parser.add2CurrIndex(tagAndAttributes.IndexOf(tagName) + tagName.Length); List <String> tokensVector = XmlParser.getTokens(parser.getXMLsubstring(endContext), XMLConstants.XML_ATTR_DELIM); Debug.Assert((tokensVector[0]).Equals(XMLConstants.MG_ATTR_VALUE)); String cachedFileUrl = (tokensVector[1]); if (cachedFileUrl.Trim() == "") // might happen in case the xpa server failed to write to its cache folder (e.g. the cache folder is invalid, due to a configuration mistake, in which case the current error message will be matched with an error in the xpa server's log file (GeneralErrorLog=)). { Logger.Instance.WriteErrorToLog(string.Format("Empty cached file URL: '{0}'", tagAndAttributes.Trim())); } else { // environment params are not metadata - they're a reflection of the server's environment params, and shouldn't be handled as a source (specifically shouldn't be collected and be accessed to the server upon switching from session stats local to remote). byte[] Content = (tagName != ConstInterface.MG_TAG_ENV_PARAM_URL ? ApplicationSourcesManager.GetInstance().ReadSource(cachedFileUrl, true) : CommandsProcessorManager.GetContent(cachedFileUrl, true)); try { switch (tagName) { case ConstInterface.MG_TAG_COLORTABLE_URL: Manager.GetColorsTable().FillFrom(Content); break; case ConstInterface.MG_TAG_FONTTABLE_URL: Manager.GetFontsTable().FillFrom(Content); break; case ConstInterface.MG_TAG_KBDMAP_URL: ClientManager.Instance.getKbdMap().fillKbdMapTable(Content); break; case ConstInterface.MG_TAG_ENV_PARAM_URL: //TODO: MerlinRT :We should parse Environment Table using MgSAXParser instead of XMLParser (the same way like we do for //Font, Color and KeyBoardMappping Table). If we do this for env, then we will have to do it for globalParamChanges as well. XmlParser innerXmlParser = new XmlParser(Encoding.UTF8.GetString(Content, 0, Content.Length)); while (ClientManager.Instance.getEnvParamsTable().mirrorFromXML(innerXmlParser.getNextTag(), innerXmlParser)) { } break; } } catch (SystemException ex) { switch (tagName) { case ConstInterface.MG_TAG_COLORTABLE_URL: Logger.Instance.WriteExceptionToLog(string.Format("Colors Table: '{0}'{1}{2}", cachedFileUrl, OSEnvironment.EolSeq, ex.Message)); break; case ConstInterface.MG_TAG_FONTTABLE_URL: Logger.Instance.WriteExceptionToLog(string.Format("Fonts Table: '{0}'{1}{2}", cachedFileUrl, OSEnvironment.EolSeq, ex.Message)); break; case ConstInterface.MG_TAG_KBDMAP_URL: Logger.Instance.WriteExceptionToLog(string.Format("Keyboard Mapping: '{0}'{1}{2}", cachedFileUrl, OSEnvironment.EolSeq, ex.Message)); break; } } } endContext = XMLdata.IndexOf(XMLConstants.TAG_OPEN, endContext); if (endContext != -1) { parser.setCurrIndex(endContext); } } }