Пример #1
0
        private static void Zserver_InitializeLogin(object sender, InitializeLoginEventArgs e)
        {
            ZServerChannel zserver_channel = (ZServerChannel)sender;

            string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n");

            if (strInstanceName == null)
            {
                string strErrorText = "通道中 实例名 '" + strInstanceName + "' 尚未初始化";
                ZManager.Log?.Error(strErrorText);
                e.Result = new Result {
                    Value = -1, ErrorInfo = strErrorText
                };
                return;
            }
            Instance instance = FindInstance(strInstanceName);

            if (instance == null)
            {
                e.Result = new Result {
                    Value = -1, ErrorInfo = "实例名 '" + strInstanceName + "' 不存在"
                };
                return;
            }

            // result.Value:
            //      -1  登录出错
            //      0   登录未成功
            //      1   登录成功

            string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u");
            string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p");

            LoginInfo login_info = new LoginInfo {
                UserName = strUserName, Password = strPassword
            };

            LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info);

            try
            {
                string strParameters = "";
                if (login_info.UserType == "patron")
                {
                    strParameters += ",type=reader";
                }
                strParameters += ",client=dp2capo|" + "0.01";

                long lRet = library_channel.Login(strUserName,
                                                  strPassword,
                                                  strParameters,
                                                  out string strError);
                e.Result.Value     = (int)lRet;
                e.Result.ErrorInfo = strError;
            }
            finally
            {
                instance.MessageConnection.ReturnChannel(library_channel);
            }
        }
Пример #2
0
        private static void Zserver_SetChannelProperty(object sender, SetChannelPropertyEventArgs e)
        {
            ZServerChannel zserver_channel = (ZServerChannel)sender;

            List <string> parts           = StringUtil.ParseTwoPart(e.Info.m_strID, "@");
            string        strUserName     = parts[0];
            string        strInstanceName = parts[1];

            string strPassword = e.Info.m_strPassword;

            // 匿名登录情形
            if (string.IsNullOrEmpty(strUserName))
            {
                Instance instance = FindInstance(strInstanceName);
                if (instance == null)
                {
                    e.Result = new Result {
                        Value     = -1,
                        ErrorCode = "InstanceNotFound",
                        ErrorInfo = "以用户名 '" + e.Info.m_strID + "' 中包含的实例名 '" + strInstanceName + "' 没有找到任何实例"
                    };
                    return;
                }

                // 如果定义了允许匿名登录
                if (String.IsNullOrEmpty(instance.zhost.AnonymousUserName) == false)
                {
                    strUserName = instance.zhost.AnonymousUserName;
                    strPassword = instance.zhost.AnonymousPassword;
                }
                else
                {
                    e.Result = new Result {
                        Value     = -1,
                        ErrorCode = "AnonymouseLoginDenied",
                        ErrorInfo = "不允许匿名登录"
                    };
                    return;
                }
            }

            // 让 channel 从此携带 Instance Name
            zserver_channel.SetProperty().SetKeyValue("i_n", strInstanceName);
            zserver_channel.SetProperty().SetKeyValue("i_u", strUserName);
            zserver_channel.SetProperty().SetKeyValue("i_p", strPassword);

            Debug.Assert(e.Result != null, "");
        }
Пример #3
0
        private static void Zserver_GetZConfig(object sender, GetZConfigEventArgs e)
        {
            ZServerChannel zserver_channel = (ZServerChannel)sender;

#if NO
            List <string> parts           = StringUtil.ParseTwoPart(e.Info.m_strID, "@");
            string        strInstanceName = parts[1];
#endif
            string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n");
            if (strInstanceName == null)
            {
                string strError = "通道中 实例名 '" + strInstanceName + "' 尚未初始化";
                ZManager.Log.Error(strError);
                e.ZConfig          = null;
                e.Result.ErrorInfo = strError;
                return;
            }

            Instance instance = FindInstance(strInstanceName);
            if (instance == null)
            {
                e.ZConfig          = null;
                e.Result.ErrorInfo = "以用户名 '" + e.Info.m_strID + "' 中包含的实例名 '" + strInstanceName + "' 没有找到任何实例";
                return;
            }

            // 让 channel 携带 Instance Name
            // zserver_channel.SetProperty().SetKeyValue("i_n", strInstanceName);

            e.ZConfig = new ZConfig
            {
                AnonymousUserName = instance.zhost.AnonymousUserName,
                AnonymousPassword = instance.zhost.AnonymousPassword,
            };
        }
Пример #4
0
 // 取出先前记忆的全局结果集名列表
 // parameters:
 //      bRemove 是否在返回前自动删除 key_object 集合中的值
 static List <string> GetResultSetNameList(ZServerChannel zserver_channel,
                                           bool bRemove = false)
 {
     lock (zserver_channel)
     {
         if (!(zserver_channel.SetProperty().GetKeyObject("r_n") is List <string> names))
         {
             return(new List <string>());
         }
         else
         {
             if (bRemove)
             {
                 zserver_channel.SetProperty().SetKeyObject("r_n", null);
             }
         }
         return(names);
     }
 }
Пример #5
0
        // 记忆全局结果集名
        static void MemoryResultSetName(ZServerChannel zserver_channel,
                                        string resultset_name)
        {
            if (!(zserver_channel.SetProperty().GetKeyObject("r_n") is List <string> names))
            {
                names = new List <string>();
                zserver_channel.SetProperty().SetKeyObject("r_n", names);
            }

            if (names.IndexOf(resultset_name) == -1)
            {
                names.Add(resultset_name);
            }

            // 如果结果集名数量太多,就要开始删除
            if (names.Count > MAX_RESULTSET_COUNT)
            {
                FreeGlobalResultSets(zserver_channel, names);
            }
        }
Пример #6
0
        static void FreeGlobalResultSets(ZServerChannel zserver_channel,
                                         List <string> names)
        {
            string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n");

            if (strInstanceName == null)
            {
                string strError = "通道中 实例名 '" + strInstanceName + "' 尚未初始化";
                ZManager.Log?.Error(strError);
            }
            Instance instance = FindInstance(strInstanceName);

            if (instance == null)
            {
                string strError = "实例名 '" + strInstanceName + "' 不存在";
                // 写入错误日志
                ZManager.Log?.Error(strError);
                return;
            }

            // TODO: 交给 Instance 释放
            instance.AddGlobalResultSets(names);

#if NO
            LibraryChannel library_channel = instance.MessageConnection.GetChannel(null);
            try
            {
                foreach (string name in names)
                {
                    // TODO: 要是能用通配符来删除大量结果集就好了
                    long lRet = library_channel.GetSearchResult("",
                                                                0,
                                                                0,
                                                                "@remove:" + name,
                                                                "zh",
                                                                out DigitalPlatform.LibraryClient.localhost.Record[] searchresults,
                                                                out string strError);
                    if (lRet == -1)
                    {
                        // 写入错误日志
                        return;
                    }
                }
            }
            finally
            {
                instance.MessageConnection.ReturnChannel(library_channel);
            }
#endif
        }
Пример #7
0
        private static void Zserver_PresentGetRecords(object sender, PresentGetRecordsEventArgs e)
        {
            string strError = "";

            ZServerChannel zserver_channel = (ZServerChannel)sender;

            string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n");

            if (strInstanceName == null)
            {
                strError = "通道中 实例名 '" + strInstanceName + "' 尚未初始化";
                ZManager.Log.Error(strError);
                goto ERROR1;
            }
            Instance instance = FindInstance(strInstanceName);

            if (instance == null)
            {
                strError = "实例名 '" + strInstanceName + "' 不存在";
                goto ERROR1;
            }

            string strResultSetName = e.Request.m_strResultSetID;

            if (String.IsNullOrEmpty(strResultSetName) == true)
            {
                strResultSetName = "default";
            }
            long lStart  = e.Request.m_lResultSetStartPoint - 1;
            long lNumber = e.Request.m_lNumberOfRecordsRequested;

            int MAX_PRESENT_RECORD = 100;

            // 限制每次 present 的记录数量
            if (lNumber > MAX_PRESENT_RECORD)
            {
                lNumber = MAX_PRESENT_RECORD;
            }

            DiagFormat            diag    = null;
            List <RetrivalRecord> records = new List <RetrivalRecord>();

            string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u");
            string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p");

            LoginInfo login_info = new LoginInfo {
                UserName = strUserName, Password = strPassword
            };
            LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info);

            try
            {
                // 全局结果集名
                string resultset_name = MakeGlobalResultSetName(zserver_channel, strResultSetName);

                ResultSetLoader loader = new ResultSetLoader(library_channel,
                                                             resultset_name,
                                                             "id,xml,timestamp")
                {
                    Start     = lStart,
                    BatchSize = Math.Min(10, lNumber)
                };
                int i     = 0;
                int nSize = 0;
                foreach (DigitalPlatform.LibraryClient.localhost.Record dp2library_record in loader)
                {
                    if (i >= lNumber)
                    {
                        break;
                    }

                    if (i == 0)
                    {
                        e.TotalCount = loader.TotalCount;
                        if (lStart >= loader.TotalCount)
                        {
                            DiagFormat diag1 = null;
                            ZProcessor.SetPresentDiagRecord(ref diag1,
                                                            13, // Present request out-of-range
                                                            "Present 所请求的起始偏移位置 " + lStart + " 超过结果集中记录总数 " + loader.TotalCount);
                            e.Diag = diag1;
                            return;
                        }
                    }

                    {
                        // 解析出数据库名和ID
                        string strDbName = dp2StringUtil.GetDbName(dp2library_record.Path);
                        string strRecID  = dp2StringUtil.GetRecordID(dp2library_record.Path);

                        // 如果取得的是xml记录,则根元素可以看出记录的marc syntax,进一步可以获得oid;
                        // 如果取得的是MARC格式记录,则需要根据数据库预定义的marc syntax来看出oid了
                        string strMarcSyntaxOID = GetMarcSyntaxOID(instance, strDbName);

                        RetrivalRecord record = new RetrivalRecord
                        {
                            m_strDatabaseName = strDbName
                        };

                        // 根据书目库名获得书目库属性对象
                        BiblioDbProperty prop = instance.zhost.GetDbProperty(
                            strDbName,
                            false);

                        int nRet = GetIso2709Record(dp2library_record,
                                                    e.Request.m_elementSetNames,
                                                    prop != null ? prop.AddField901 : false,
                                                    prop != null ? prop.RemoveFields : "997",
                                                    zserver_channel.SetProperty().MarcRecordEncoding,
                                                    out byte[] baIso2709,
                                                    out strError);

                        /*
                         *                      // 测试记录群中包含诊断记录
                         *                      if (i == 1)
                         *                      {
                         *                          nRet = -1;
                         *                          strError = "测试获取记录错误";
                         *                      }
                         */
                        if (nRet == -1)
                        {
                            record.m_surrogateDiagnostic = new DiagFormat
                            {
                                m_strDiagSetID   = "1.2.840.10003.4.1",
                                m_nDiagCondition = 14,  // system error in presenting records
                                m_strAddInfo     = strError
                            };
                        }
                        else if (nRet == 0)
                        {
                            record.m_surrogateDiagnostic = new DiagFormat
                            {
                                m_strDiagSetID   = "1.2.840.10003.4.1",
                                m_nDiagCondition = 1028,  // record deleted
                                m_strAddInfo     = strError
                            };
                        }
                        else if (String.IsNullOrEmpty(strMarcSyntaxOID) == true)
                        {
                            // 根据数据库名无法获得marc syntax oid。可能是虚拟库检索命中记录所在的物理库没有在 capo.xml 中配置。
                            record.m_surrogateDiagnostic = new DiagFormat
                            {
                                m_strDiagSetID   = "1.2.840.10003.4.1",
                                m_nDiagCondition = 109,  // database unavailable // 似乎235:database dos not exist也可以
                                m_strAddInfo     = "根据数据库名 '" + strDbName + "' 无法获得 marc syntax oid"
                            };
                        }
                        else
                        {
                            record.m_external = new External
                            {
                                m_strDirectRefenerce = strMarcSyntaxOID,
                                m_octectAligned      = baIso2709
                            };
                        }

                        nSize += record.GetPackageSize();

                        if (i == 0)
                        {
                            // 连一条记录也放不下
                            if (nSize > zserver_channel.SetProperty().ExceptionalRecordSize)
                            {
                                Debug.Assert(diag == null, "");
                                ZProcessor.SetPresentDiagRecord(ref diag,
                                                                17, // record exceeds Exceptional_record_size
                                                                "记录尺寸 " + nSize.ToString() + " 超过 Exceptional_record_size " + zserver_channel.SetProperty().ExceptionalRecordSize.ToString());
                                lNumber = 0;
                                break;
                            }
                        }
                        else
                        {
                            if (nSize >= zserver_channel.SetProperty().PreferredMessageSize)
                            {
                                // 调整返回的记录数
                                lNumber = i;
                                break;
                            }
                        }

                        records.Add(record);
                    }

                    i++;
                }
            }
            catch (Exception ex)
            {
                strError = "获取结果集时出现异常: " + ex.Message;
                goto ERROR1;
            }
            finally
            {
                instance.MessageConnection.ReturnChannel(library_channel);
            }

            e.Records = records;
            e.Diag    = diag;
            return;

ERROR1:
            {
                DiagFormat diag1 = null;
                ZProcessor.SetPresentDiagRecord(ref diag1,
                                                2, // temporary system error
                                                strError);
                e.Diag = diag1;
                // e.Result = new ZClient.SearchResult { Value = -1, ErrorInfo = strError };
                return;
            }
        }
Пример #8
0
        private static void Zserver_SearchSearch(object sender, SearchSearchEventArgs e)
        {
            ZServerChannel zserver_channel = (ZServerChannel)sender;

            string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n");

            if (strInstanceName == null)
            {
                string strErrorText = "通道中 实例名 '" + strInstanceName + "' 尚未初始化";
                ZManager.Log?.Error(strErrorText);
                e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult {
                    Value = -1, ErrorInfo = strErrorText
                };
                return;
            }
            Instance instance = FindInstance(strInstanceName);

            if (instance == null)
            {
                e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult {
                    Value = -1, ErrorInfo = "实例名 '" + strInstanceName + "' 不存在"
                };
                return;
            }

            // 根据逆波兰表构造出 dp2 系统检索式

            // return:
            //      -1  error
            //      0   succeed
            int nRet = Z3950Utility.BuildQueryXml(
                instance.zhost,
                e.Request.m_dbnames,
                e.Request.m_rpnRoot,
                zserver_channel.SetProperty().SearchTermEncoding,
                out string strQueryXml,
                out string strError);

            if (nRet == -1)
            {
                DiagFormat diag = null;
                ZProcessor.SetPresentDiagRecord(ref diag,
                                                2, // temporary system error
                                                strError);
                e.Diag   = diag;
                e.Result = new ZClient.SearchResult {
                    Value = -1, ErrorInfo = strError
                };
                return;
            }

            string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u");
            string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p");

            LoginInfo login_info = new LoginInfo {
                UserName = strUserName, Password = strPassword
            };

            LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info);

            try
            {
                // 全局结果集名
                string resultset_name = MakeGlobalResultSetName(zserver_channel, e.Request.m_strResultSetName);
                // 进行检索
                long lRet = library_channel.Search(
                    strQueryXml,
                    resultset_name,
                    "", // strOutputStyle
                    out strError);

                /*
                 * // 测试检索失败
                 * lRet = -1;
                 * strError = "测试检索失败";
                 * */

                if (lRet == -1)
                {
                    DiagFormat diag = null;
                    ZProcessor.SetPresentDiagRecord(ref diag,
                                                    2, // temporary system error
                                                    strError);
                    e.Diag   = diag;
                    e.Result = new ZClient.SearchResult {
                        Value = -1, ErrorInfo = strError
                    };
                    return;
                }
                else
                {
                    // 记忆结果集名
                    MemoryResultSetName(zserver_channel, resultset_name);

                    e.Result = new ZClient.SearchResult {
                        ResultCount = lRet
                    };
                }
            }
            finally
            {
                instance.MessageConnection.ReturnChannel(library_channel);
            }
        }