搜索​​​​

清除过滤器
文章
Jingwei Wang · 十月 28, 2021

IRIS 2021 技术文档 First Look 31:InterSystems IRIS 和 UIMA

html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; } .mac-os-11 { --title-bar-height: 28px; } html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; } body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; } iframe { margin: auto; } a.url { word-break: break-all; } a:active, a:hover { outline: 0px; } .in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); } #write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; } #write.first-line-indent p { text-indent: 2em; } #write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; } #write.first-line-indent li { margin-left: 2em; } .for-image #write { padding-left: 8px; padding-right: 8px; } body.typora-export { padding-left: 30px; padding-right: 30px; } .typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; } .typora-export .task-list-item input { pointer-events: none; } @media screen and (max-width: 500px) { body.typora-export { padding-left: 0px; padding-right: 0px; } #write { padding-left: 20px; padding-right: 20px; } .CodeMirror-sizer { margin-left: 0px !important; } .CodeMirror-gutters { display: none !important; } } #write li > figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max-width: 100%; vertical-align: middle; image-orientation: from-image; } button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; } input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; } *, ::after, ::before { box-sizing: border-box; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; } p { line-height: inherit; } h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; } p { orphans: 4; } h1 { font-size: 2rem; } h2 { font-size: 1.8rem; } h3 { font-size: 1.6rem; } h4 { font-size: 1.4rem; } h5 { font-size: 1.2rem; } h6 { font-size: 1rem; } .md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; } .hidden { display: none; } .md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; } a { cursor: pointer; } sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; } #write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; } figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; } figure > table { margin: 0px; } tr { break-inside: avoid; break-after: auto; } thead { display: table-header-group; } table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; } table.md-table td { min-width: 32px; } .CodeMirror-gutters { border-right-width: 0px; background-color: inherit; } .CodeMirror-linenumber { } .CodeMirror { text-align: left; } .CodeMirror-placeholder { opacity: 0.3; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-lines { padding: 0px; } div.hr:focus { cursor: none; } #write pre { white-space: pre-wrap; } #write.fences-no-line-wrapping pre { white-space: pre; } #write pre.ty-contain-cm { white-space: normal; } .CodeMirror-gutters { margin-right: 4px; } .md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; } .md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; } #write .md-fences.mock-cm { white-space: pre-wrap; } .md-fences.md-fences-with-lineno { padding-left: 0px; } #write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; } .md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; } .CodeMirror-line, twitterwidget { break-inside: avoid; } .footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; } .footnotes + .footnotes { margin-top: 0px; } .md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; } li div { padding-top: 0px; } blockquote { margin: 1rem 0px; } li .mathjax-block, li p { margin: 0.5rem 0px; } li blockquote { margin: 1rem 0px; } li { margin: 0px; position: relative; } blockquote > :last-child { margin-bottom: 0px; } blockquote > :first-child, li > :first-child { margin-top: 0px; } .footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; } #write .footnote-line { white-space: pre-wrap; } @media print { body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; } #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; } .typora-export * { -webkit-print-color-adjust: exact; } .typora-export #write { break-after: avoid; } .typora-export #write::after { height: 0px; } .is-mac table { break-inside: avoid; } .typora-export-show-outline .typora-export-sidebar { display: none; } } .footnote-line { margin-top: 0.714em; font-size: 0.7em; } a img, img a { cursor: pointer; } pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; } p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; } #write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; } p > .md-image:only-child { display: inline-block; width: 100%; } #write .MathJax_Display { margin: 0.8em 0px 0px; } .md-math-block { width: 100%; } .md-math-block:not(:empty)::after { display: none; } .MathJax_ref { fill: currentcolor; } [contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; } .md-task-list-item { position: relative; list-style-type: none; } .task-list-item.md-task-list-item { padding-left: 0px; } .md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; } .math { font-size: 1rem; } .md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; } .md-toc-content { position: relative; margin-left: 0px; } .md-toc-content::after, .md-toc::after { display: none; } .md-toc-item { display: block; color: rgb(65, 131, 196); } .md-toc-item a { text-decoration: none; } .md-toc-inner:hover { text-decoration: underline; } .md-toc-inner { display: inline-block; cursor: pointer; } .md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; } .md-toc-h2 .md-toc-inner { margin-left: 2em; } .md-toc-h3 .md-toc-inner { margin-left: 4em; } .md-toc-h4 .md-toc-inner { margin-left: 6em; } .md-toc-h5 .md-toc-inner { margin-left: 8em; } .md-toc-h6 .md-toc-inner { margin-left: 10em; } @media screen and (max-width: 48em) { .md-toc-h3 .md-toc-inner { margin-left: 3.5em; } .md-toc-h4 .md-toc-inner { margin-left: 5em; } .md-toc-h5 .md-toc-inner { margin-left: 6.5em; } .md-toc-h6 .md-toc-inner { margin-left: 8em; } } a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; } .footnote-line a:not(.reversefootnote) { color: inherit; } .md-attr { display: none; } .md-fn-count::after { content: "."; } code, pre, samp, tt { font-family: var(--monospace); } kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; } .md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); } code { text-align: left; } a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; } .md-inline-math .MathJax_SVG .noError { display: none !important; } .html-for-mac .inline-math-svg .MathJax_SVG { vertical-align: 0.2px; } .md-fences-math .MathJax_SVG_Display, .md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: visible; display: block !important; } .MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; } .MathJax_SVG .MJX-monospace { font-family: var(--monospace); } .MathJax_SVG .MJX-sans-serif { font-family: sans-serif; } .MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; zoom: 90%; } #math-inline-preview-content { zoom: 1.1; } .MathJax_SVG * { transition: none; } .MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; margin-top: 0px !important; } .os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; } .md-diagram-panel > svg { max-width: 100%; } [lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; } [lang="mermaid"] .node text { font-size: 1rem; } table tr th { border-bottom-width: 0px; } video { max-width: 100%; display: block; margin: 0px auto; } iframe { max-width: 100%; width: 100%; border: none; } .highlight td, .highlight tr { border: 0px; } mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); } .md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; } .md-expand mark .md-meta { opacity: 0.3 !important; } mark .md-meta { color: rgb(0, 0, 0); } @media print { .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; } } .md-diagram-panel .messageText { stroke: none !important; } .md-diagram-panel .start-state { fill: var(--node-fill); } .md-diagram-panel .edgeLabel rect { opacity: 1 !important; } .md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); } .md-fences.md-fences-math { font-size: 1em; } .md-fences-math .MathJax_SVG_Display { margin-top: 8px; cursor: default; } .md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; } .md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; } .typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; } .typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; } .typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; } @media screen and (max-width: 1024px) { .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; } } @media screen and (max-width: 800px) { .typora-export-sidebar { display: none; } } .outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; } .outline-content ul { margin-top: 0px; margin-bottom: 0px; } .outline-content strong { font-weight: 400; } .outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; } .outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; } .outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; } .outline-expander:hover::before { content: ''; } .outline-h1 > .outline-item { padding-left: 0px; } .outline-h2 > .outline-item { padding-left: 1em; } .outline-h3 > .outline-item { padding-left: 2em; } .outline-h4 > .outline-item { padding-left: 3em; } .outline-h5 > .outline-item { padding-left: 4em; } .outline-h6 > .outline-item { padding-left: 5em; } .outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; } .outline-label:hover { text-decoration: underline; } .outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); } .outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; } .outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; } .outline-item-open > .outline-item > .outline-expander::before { content: ''; } .outline-children { display: none; } .info-panel-tab-wrapper { display: none; } .outline-item-open > .outline-children { display: block; } .typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; } .typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; } .typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; } .typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; } .typora-export-collapse-outline .outline-children { display: none; } .typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; } .typora-export-no-collapse-outline .outline-expander::before { content: "" !important; } .typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; } .CodeMirror { height: auto; } .CodeMirror.cm-s-inner { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-scroll { overflow: auto hidden; z-index: 3; } .CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); } .CodeMirror-gutters { border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; white-space: nowrap; background-position: inherit; background-repeat: inherit; } .CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); } .cm-s-inner .cm-keyword { color: rgb(119, 0, 136); } .cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); } .cm-s-inner .cm-number { color: rgb(17, 102, 68); } .cm-s-inner .cm-def { color: rgb(0, 0, 255); } .cm-s-inner .cm-variable { color: rgb(0, 0, 0); } .cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); } .cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); } .cm-s-inner .cm-string { color: rgb(170, 17, 17); } .cm-s-inner .cm-property { color: rgb(0, 0, 0); } .cm-s-inner .cm-operator { color: rgb(152, 26, 26); } .cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); } .cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); } .cm-s-inner .cm-meta { color: rgb(85, 85, 85); } .cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); } .cm-s-inner .cm-builtin { color: rgb(51, 0, 170); } .cm-s-inner .cm-bracket { color: rgb(153, 153, 119); } .cm-s-inner .cm-tag { color: rgb(17, 119, 0); } .cm-s-inner .cm-attribute { color: rgb(0, 0, 204); } .cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); } .cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); } .cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); } .cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); } .cm-negative { color: rgb(221, 68, 68); } .cm-positive { color: rgb(34, 153, 34); } .cm-header, .cm-strong { font-weight: 700; } .cm-del { text-decoration: line-through; } .cm-em { font-style: italic; } .cm-link { text-decoration: underline; } .cm-error { color: red; } .cm-invalidchar { color: red; } .cm-constant { color: rgb(38, 139, 210); } .cm-defined { color: rgb(181, 137, 0); } div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); } div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); } .cm-s-inner .CodeMirror-activeline-background { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror { position: relative; overflow: hidden; } .CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-sizer { position: relative; } .CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; } .CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; } .CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: hidden; } .CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; } .CodeMirror-gutter-filler { left: 0px; bottom: 0px; } .CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; } .CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; } .CodeMirror-gutter-wrapper { position: absolute; z-index: 4; border: none !important; background-position: 0px 0px !important; } .CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; } .CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; } .CodeMirror-lines { cursor: text; } .CodeMirror pre { border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; border-width: 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; background-position: 0px 0px; } .CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; } .CodeMirror-code pre { border-right-width: 30px; border-right-style: solid; border-right-color: transparent; width: fit-content; } .CodeMirror-wrap .CodeMirror-code pre { border-right-style: none; width: auto; } .CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; } .CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; } .CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; } .CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; } .CodeMirror-measure pre { position: static; } .CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right-style: none; width: 0px; } .CodeMirror div.CodeMirror-cursor { visibility: hidden; } .CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; } .cm-searching { background-color: rgba(255, 255, 0, 0.4); } span.cm-underlined { text-decoration: underline; } span.cm-strikethrough { text-decoration: line-through; } .cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); } .cm-tw-deleted { text-decoration: line-through; } .cm-tw-header5 { font-weight: 700; } .cm-tw-listitem:first-child { padding-left: 10px; } .cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; } .cm-tw-underline { text-decoration: underline; } @media print { .CodeMirror div.CodeMirror-cursor { visibility: hidden; } } :root { --side-bar-bg-color: #fafafa; --control-text-color: #777; } @include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext); /* open-sans-regular - latin-ext_latin */ /* open-sans-italic - latin-ext_latin */ /* open-sans-700 - latin-ext_latin */ /* open-sans-700italic - latin-ext_latin */ html { font-size: 16px; } body { font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; color: rgb(51, 51, 51); line-height: 1.6; } #write { max-width: 860px; margin: 0 auto; padding: 30px; padding-bottom: 100px; } @media only screen and (min-width: 1400px) { #write { max-width: 1024px; } } @media only screen and (min-width: 1800px) { #write { max-width: 1200px; } } #write > ul:first-child, #write > ol:first-child{ margin-top: 30px; } a { color: #4183C4; } h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid #eee; } h2 { font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid #eee; } /*@media print { .typora-export h1, .typora-export h2 { border-bottom: none; padding-bottom: initial; } .typora-export h1::after, .typora-export h2::after { content: ""; display: block; height: 100px; margin-top: -96px; border-top: 1px solid #eee; } }*/ h3 { font-size: 1.5em; line-height: 1.43; } h4 { font-size: 1.25em; } h5 { font-size: 1em; } h6 { font-size: 1em; color: #777; } p, blockquote, ul, ol, dl, table{ margin: 0.8em 0; } li>ol, li>ul { margin: 0 0; } hr { height: 2px; padding: 0; margin: 16px 0; background-color: #e7e7e7; border: 0 none; overflow: hidden; box-sizing: content-box; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul:first-child, ol:first-child { margin-top: 0; } ul:last-child, ol:last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dfe2e5; padding: 0 15px; color: #777777; } blockquote blockquote { padding-right: 0; } table { padding: 0; word-break: initial; } table tr { border: 1px solid #dfe2e5; margin: 0; padding: 0; } table tr:nth-child(2n), thead { background-color: #f8f8f8; } table th { font-weight: bold; border: 1px solid #dfe2e5; border-bottom: 0; margin: 0; padding: 6px 13px; } table td { border: 1px solid #dfe2e5; margin: 0; padding: 6px 13px; } table th:first-child, table td:first-child { margin-top: 0; } table th:last-child, table td:last-child { margin-bottom: 0; } .CodeMirror-lines { padding-left: 4px; } .code-tooltip { box-shadow: 0 1px 1px 0 rgba(0,28,36,.3); border-top: 1px solid #eef2f2; } .md-fences, code, tt { border: 1px solid #e7eaed; background-color: #f8f8f8; border-radius: 3px; padding: 0; padding: 2px 4px 0px 4px; font-size: 0.9em; } code { background-color: #f3f4f4; padding: 0 2px 0 2px; } .md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; } .md-task-list-item > input { margin-left: -1.3em; } @media print { html { font-size: 13px; } table, pre { page-break-inside: avoid; } pre { word-wrap: break-word; } } .md-fences { background-color: #f8f8f8; } #write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: #f7f7f7; border: 0; border-radius: 3px; color: #777777; margin-top: 0 !important; } .mathjax-block>.code-tooltip { bottom: .375rem; } .md-mathjax-midline { background: #fafafa; } #write>h3.md-focus:before{ left: -1.5625rem; top: .375rem; } #write>h4.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h5.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h6.md-focus:before{ left: -1.5625rem; top: .285714286rem; } .md-image>.md-meta { /*border: 1px solid #ddd;*/ border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; } .md-tag { color: #a7a7a7; opacity: 1; } .md-toc { margin-top:20px; padding-bottom:20px; } .sidebar-tabs { border-bottom: none; } #typora-quick-open { border: 1px solid #ddd; background-color: #f8f8f8; } #typora-quick-open-item { background-color: #FAFAFA; border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; border-style: solid; border-width: 1px; } /** focus mode */ .on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); } header, .context-menu, .megamenu-content, footer{ font-family: "Segoe UI", "Arial", sans-serif; } .file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state{ visibility: visible; } .mac-seamless-mode #typora-sidebar { background-color: #fafafa; background-color: var(--side-bar-bg-color); } .md-lang { color: #b4654d; } /*.html-for-mac { --item-hover-bg-color: #E6F0FE; }*/ #md-notification .btn { border: 0; } .dropdown-menu .divider { border-color: #e5e5e5; opacity: 0.4; } .ty-preferences .window-content { background-color: #fafafa; } .ty-preferences .nav-group-item.active { color: white; background: #999; } .menu-item-container a.menu-style-btn { background-color: #f5f8fa; background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); } :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} 目录 技术概要:InterSystems IRIS 和 UIMA关于 UIMAInterSystems IRIS 如何补充 UIMA Annotation Store(注释存储) InterSystems IRIS NLP在 InterSystems IRIS 中体验 UIMA 用前须知 创建新的命名空间 运行Java Gateway(Java 网关) 体验 UIMA 分析管道 浏览 Annotation Store(注释存储) 通过分析管道发送新文本 向 Aviation.Event 表添加记录 查看Annotation Store(注释存储)中的新条目了解更多关于 UIMA的资料 技术概要:InterSystems IRIS 和 UIMA 本技术概要(First Look)快速介绍了 InterSystems IRIS® 数据平台如何实施和补充非结构化信息管理架构 (UIMA)。在简要概述 UIMA 以及 InterSystems IRIS 如何对其进行补充之后,您将有机会通过基本的动手练习来在实际应用中了解 InterSystems IRIS。 要浏览技术概要(First Look)的所有内容,包括可以在InterSystems IRIS的免费评估实例上执行的内容,请参阅InterSystems 技术概要。 关于 UIMA UIMA 是管理分析非结构化信息(如文本和视频)的标准。对于非结构化信息,计算机通常需要几个步骤才能将信息转化为可操作的结构化数据。例如,扫描的文档将文本转变为机器可读版本之前需要OCR,即使这样,在应用额外的 NLP 策略之前,计算机也不能很好地处理自然语言文本。由于像这样的流程包括本质上非常不同的步骤,因此单个工具不太可能处理所有这些步骤。更可能的情况是,这个流程包括单独模块,这些模块由使用不同技术的不同主体执行,且需要协同工作。在 UIMA 中,这些模块被称为analysis engines(分析引擎)。 因为符合 UIMA 标准的分析引擎都遵循相同的标准,所以它们可以组合成一系列分析器(a UIMA analysis pipeline [UIMA 分析管道]),每个部分做自己最擅长的事情。源非结构化数据在通过此 UIMA 分析管道时不会发生改变,而是沿途生成annotations(注释)。UIMA 标准确保来自一个分析引擎的注释不会干扰来自不同分析引擎的注释。对于文本,这些注释基于文本中的字符位置。UIMA 的互操作性允许您将来自不同供应商和技术的分析引擎组合到一个管道中,而无需编写任何自定义代码,并且由于分析引擎引用原始源数据中的字符位置,因此它们的注释可以组合、比较和推理。UIMA 标准包括运行这些分析引擎中所执行的框架。 除了提供互操作性之外,UIMA 还提供了用于扩展和部署这些分析引擎的框架。这使供应商可以专注于开发分析引擎,而不必担心扩展和部署他们的解决方案。[]{#2_How_InterSystems_IRIS_Complements_UIMA .anchor}UIMA 标准还提供了在分布式架构中调用这些分析引擎的框架。 每个符合 UIMA 的分析引擎都必须附带一个 XML 描述符文件,该文件包含基本识别信息,例如分析引擎的名称和供应商。它还定义了对分析引擎生成的注释进行分类的注释类型。 InterSystems IRIS 如何补充 UIMA InterSystems IRIS 在三个方面补充了 UIMA: 引入功能索引以创建 UIMA 分析管道(analysis pipeline),并在 InterSystems IRIS 表中插入或更新记录时自动为该分析管道提供新文本。 将 UIMA 分析管道生成的注释存储在 InterSystems IRIS 中清晰、可通过 SQL 访问的Annotation Store(注释存储)中。 在 InterSystems IRIS 中体验 UIMA 确保 InterSystems IRIS Natural Language Processing(InterSystems IRIS 自然语言处理, NLP )符合 UIMA 标准,并可用作 UIMA 分析管道中的分析引擎。 创建和调用 UIMA 分析管道 InterSystems IRIS 使用functional index(功能索引)以创建 UIMA 分析管道,该管道使用 InterSystems IRIS 概念,而无需担心实现 Java 接口。功能索引是 InterSystems IRIS 数据库的一项功能,它允许在表中插入或更新记录时执行功能。在这种情况下,功能索引是定义在表的列上,该列包含您希望由 UIMA 分析管道分析的非结构化数据。设置该管道就像将分析引擎描述文件的位置添加到功能索引定义一样简单。 一旦定义了功能索引,只要在索引表列中插入或更新最新数据,InterSystems IRIS 就会自动将非结构化数据输入 UIMA 分析管道。例如,如果在包含报表的列上定义了功能索引,那么将新报表添加到表中后立即对其进行分析。没有[]{#2.2_Annotation_Store .anchor} InterSystems IRIS 中的这一特殊功能,每次您想要分析数据时,都需要在 Java 中以编程方式通过管道发送非结构化数据。 Annotation Store(注释存储) 默认情况下,UIMA 分析管道的结果被存储在冗长繁琐的 XML 文件中。由于 UIMA 标准没有提供更复杂的注释存储方法,InterSystems IRIS 通过使用灵活的、基于 SQL 的存储,将注释放在统一、持久的表中以便后续检索,从而扩展了 UIMA 分析管道。这种存储系统称为Annotation Store(注释存储)。 在您第一次编译包含为创建 UIMA 分析管道定义的功能索引的类时,会自动创建此Annotation Store(注释存储)。它直接链接到包含非结构化数据的原始表的列。 在架构上,Annotation Store(注释存储) 是通过添加一个特殊的分析引擎作为 UIMA 分析管道的最后一个组件来生成的。当您将 UIMA 功能索引添加到 InterSystems IRIS 类时,将会自动生成Annotation Store(注释存储)。在 InterSystems IRIS 之外开发的 UIMA 分析管道也可以将此特殊分析引擎添加到管道末端,以创建Annotation Store(注释存储)。这种实现方式超出了本技术概要(First Look)的讨论范围。 []{#2.3_InterSystems_IRIS_NLP .anchor}您还可以使用XData block在包含功能索引的类中自定义Annotation Store(注释存储)。例如,您可以为每个表定义额外的列和索引。您还可以筛选注释类型,以将它们排除在Annotation Store(注释存储)之外。 InterSystems IRIS NLP InterSystems IRIS Natural Language Processing(InterSystems IRIS 自然语言处理, NLP )被内置到 InterSystems IRIS® 数据平台中,可以在预先不了解这些非结构化文本主题的情况下,对这些文本进行文本分析。它通过应用识别语义实体的特定语言规则来实现这项功能。由于这些规则是专门针对语言而非内容,因此 InterSystems IRIS NLP可以在不使用字典或本体的情况下提供对文本内容的深入分析 您可以使用 InterSystems IRIS NLP 作为 UIMA 分析引擎,为 NLP 概念和上下文生成 UIMA 注释。这些注释与其他 UIMA 分析引擎提供的 UIMA 注释完全兼容。 在 InterSystems IRIS 中体验 UIMA 现在您已经了解了有关 UIMA 的一些基本信息,可以动手体验以了解它在 InterSystems IRIS 中的工作原理。在体验之前,您需要设置环境。 在 InterSystems IRIS 中体验 UIMA 用前须知 首先,请执行以下初步设置任务: 安装 Java Runtime Environment(Java 运行时环境)。 安装 InterSystems IRIS。 创建一个新的 InterSystems IRIS 命名空间。 启动 Java Gateway(Java 网关)。 安装 Java Runtime Environment(Java 运行环境) InterSystems IRIS 进行 UIMA 分析管道分析需要安装Java Runtime Environment(Java 运行时环境,JRE)。还需要一个指向 JRE 安装位置的环境变量。 如果您的机器上尚未安装 JRE,请从 Oracle® 下载并安装最新版本。 创建一个名为JAVA_HOME的环境变量,该变量指向 JRE 安装的位置。例如,在 Windows® 上,使用 Control Panel(控制面板)创建JAVA_HOME环境变量,并定义该变量到 JRE 安装位置的路径。 安装 InterSystems IRIS 要运行 UIMA 分析管道的演示,您需要一个运行中的 InterSystems IRIS 已授权的实例。 有关如何安装和授权 InterSystems IRIS 开发实例的说明,请参阅InterSystems IRIS Basics: Installation (《InterSystems IRIS 基础知识:安装》)。 创建新的命名空间 作为技术概要(First Look)体验的一部分,您将向 InterSystems IRIS 中的命名空间添加一个新类文件。为了使此示例数据与预定义的命名空间分开,请创建一个名为 SAMPLES 的新命名空间来保存与此技术概要(First Look)关联的代码和数据。创建一个新的命名空间: 在浏览器中打开 Management Portal (管理门户),使用 InterSystems IRIS Basics: Connecting an IDE(《INTERSYSTEMS IRIS 基础:连接一个IDE 》)的实例适用的URL。 选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Namespaces(命名空间)。 在 Namespaces(命名空间)页面,选择 Create New Namespace(新建命名空间)。 在 New Namespace(新建命名空间)页面,输入SAMPLES作为新命名空间的名称。 点击 Create New Database(新建数据库),将显示 Database Wizard(数据库向导)。 在 Database Wizard(数据库向导)的第一页,在 Enter the name of your database(输入您的数据库名称)字段,输入您正在创建的数据库的名称,例如 Samplesdb。 输入数据库的目录,例如 C:\InterSystems\IRIS\mgr\Samplesdb 。 点击 Next(下一步)。 点击 Finish(完成)。 回到New Namespace(新命名空间)页面,在Select an existing database for Routines(为 Routine 选择一个现有数据库)下拉菜单,选择您刚刚创建的数据库Samplesdb。 点击靠近页面顶部的 Save(保存),然后在结果日志的末尾单击 Close(关闭)。 UIMA 分析管道 运行Java Gateway(Java 网关) Java Gateway(Java 网关)可以实例化外部 Java object(Java 对象),就好像它是 InterSystems IRIS 中的本机对象一样,可以对其进行操作。InterSystems IRIS 的 UIMA 策略使用Java Gateway(Java 网关),可以从command line (命令行)启动Java Gateway(Java 网关)。例如,在 Windows 上: 打开 Run(运行)对话框。 输入以下命令: %JAVA_HOME%\bin\java -classpath "C:\InterSystems\IRIS\dev\java\lib\JDK18\*;C:\InterSystems\IRIS\dev\java\lib\jackson\*;C:\InterSystems\IRIS \dev\java\lib\uima\*" com.intersystems.gateway.JavaGateway 5555 其中: JAVA_HOME 是指向Java Runtime Environment(Java 运行环境,JRE)安装目录位置的环境变量。 C:\InterSystems\IRIS 是您安装的 InterSystems IRIS 的目录。 JDK18 对应您的 JRE 版本。 如果在UNIX®上运行 ,请记住 -classpath 的句法使用冒号作为分隔符。 体验 UIMA 分析管道 现在您已经完成了准备工作,并已准备好在实际应用中查看 UIMA 分析管道的运行情况。在这次体验中,您将: 添加包含 UIMA 功能索引的类文件 编译包含功能索引的类。 查看 Annotation Store (注释存储)的表。 将非结构化数据添加到示例数据库。 浏览 Annotation Store(注释存储) 以获取分析管道生成的新数据。 添加带有 UIMA 功能索引的类文件 您可以通过为包含非结构化文本的表定义功能索引,向 UIMA 分析管道添加分析引擎。在本次体验中,您将向该分析管道添加 InterSystems IRIS NLP 分析引擎。 在体验的这一部分中,您将创建一个新的类文件。可以在您喜欢的文本编辑器或 IDE(例如 InterSystems Studio 或带有 ObjectScript 扩展名的 Visual Studio Code)中创建类文件。 在 IDE 或文本编辑器中创建一个新文件。 将以下内容复制并粘贴到类文件中: xxxxxxxxxx Class Sample.MyData Extends %Persistent ​ { ​ Property MyText As %String; ​ Index MyIndex On (MyText) As %UIMA.Index(AEDESCRIPTOR = \"classpath:/com/intersystems/uima/annotator/iKnowEngine.xml\"); ​ } 体验 UIMA 分析管道 其中: MyText 是包含非结构化文本的 Sample.MyData 表中的列。 MyIndex 是 UIMA 功能索引。 iKnowEngine.xml是 InterSystems IRIS NLP 分析引擎的描述符文件。 将文件另存为sample.cls。 编译表类 要自动生成 Annotation Store (注释存储),您只需使用InterSystems Terminal(InterSystems 终端)或 IDE 提供的工具编译包含功能索引的类。 建议: 使用 InterSystems Terminal(InterSystems 终端)时,您可以使用 Shift+Insert 命令将剪贴板的内容粘贴到终端命令提示符中。从本指南复制命令并将它们粘贴到终端中以减少错误,这种方式很有用。 加载和编译类: 打开 InterSystems Terminal(InterSystems 终端)。有关为您的实例打开Terminal (终端)的信息,请参阅InterSystems IRIS Basics: Connecting an IDE(《INTERSYSTEMS IRIS 基础:连接一个IDE 》)中的InterSystems IRIS Connection Information (《InterSystems IRIS 连接信息》)。 切换到您为此演示创建的命名空间。例如: set $namespace="samples" 输入以下命令,将类文件加载到命名空间中: do $system.OBJ.Load("<sample-dir>\sample.cls") 其中 <sample-dir> 是您保存 samples.cls 类文件的位置。 输入以下命令,编译您粘贴到sample.cls 的Sample.MyData 类: do $system.OBJ.Compile("Sample.MyData") 浏览 Annotation Store(注释存储) 既然您已经使用 Annotation Store UIMA 功能索引编译了类,可以浏览为保留 InterSystems IRIS NLP 生成的注释而创建的(Annotation Store )注释存储。 在浏览器中使用 URL 为实例打开 Management Portal (管理门户),如InterSystems IRIS Basics: Connecting an IDE(《INTERSYSTEMS IRIS 基础:连接一个IDE 》)的InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)所述。 使用标题中的链接切换到 Samples 命名空间。 参观 UIMA 分析管道 进入 System Explorer(系统资源管理器)> SQL 。 展开左侧窗格中的 Tables(表) 列表。 可以看到 Annotation Store (注释存储) 的三个表。这些表的命名规则对应包含所分析的非结构化文本的表 (Sample.MyData)。 Sample_MyData.Type------包含此存储中使用的Annotation Types (注释类型)的概述。 Sample_MyData.Sofa------包含 sofas,这是 UIMA 分析引擎分析的文本对象。 Sample_MyData.Annotation------包含该分析引擎生成的注释。 您可以修改功能索引定义以创建多个注释表,然后根据注释类型将结果输出到正确的表中。 通过分析管道发送新文本 InterSystems IRIS 中 UIMA 分析管道的强大之处在于,新的非结构化文本会自动通过管道发送以进行分析,并将结果添加到 Annotation Store (注释存储)中。由于您已经创建了 Annotation Store(注释存储),可以看到新纪录如何被添加到 Sample.MyData 表,并生成添加到 Annotation Store的新条目。 向 Aviation.Event 表添加记录 在本步骤中,您将使用 SQL 向示例数据库中的 Sample.MyData 表添加一些非结构化文本。请记住,该表包含MyText 列,您已在该列上定义功能索引。正如您将看到的,当进行此插入操作时,会自动生成注释。 在System Explorer (系统资源管理器 )> SQL页,展开左侧窗格中的 Tables(表) 列表。 选择 Sample.MyData,这是包含通过分析管道发送的非结构化文本的表。 在右侧窗格中,单击 Execute Query(执行查询)标签。 要将新条目插入示例数据库,请在文本框中输入以下查询 xxxxxxxxxx INSERT INTO Sample.MyData (MyText) VALUES (\'First Look unstructured text\') 点击 Execute (执行)。 这会将短语"First Look unstructured text"放入 Sample.MyData 表的 MyText 列中。 了解更多关于 UIMA的资料 查看Annotation Store(注释存储)中的新条目 现在您已将新的非结构化文本添加到示例数据库中,可以查看 Annotation Store 以了解这些文本是如何通过分析管道自动发送的。您可以看到新的非结构化文本和来自 InterSystems IRIS NLP 的注释都添加到了Annotation Store(注释存储)中。 在 System Explorer (系统资源管理器 )> SQL页,展开左侧窗格中的 Tables(表) 列表。 选择 Sample_MyData.Sofa 表。 在右侧窗格中,单击 Open Table(打开表)。 您可以看到添加到 Annotation Store 的新记录。sofaString是由分析管道处理的一段非结构化文本。 点击 Close Window(关闭窗口)。 在左侧窗格中,选择 Sample_MyData.Annotation 表。 点击 Open Table(打开表)。 在coveredText列,您可以看到由 InterSystems IRIS NLP 分析引擎生成的注释。 了解更多关于 UIMA的资料 要了解有关 InterSystems IRIS 如何实施和补充 UIMA 的更多信息,请参阅 Using InterSystems UIMA(《使用 InterSystems UIMA》)。 有关 UIMA 标准的框架、基础设施和组件的详细概述,请参阅 Apache UIMA home page
文章
Jingwei Wang · 十月 28, 2021

IRIS 2021 技术文档 First Look 26 InterSystems API 管理器

html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; } .mac-os-11 { --title-bar-height: 28px; } html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; } body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; } iframe { margin: auto; } a.url { word-break: break-all; } a:active, a:hover { outline: 0px; } .in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); } #write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; } #write.first-line-indent p { text-indent: 2em; } #write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; } #write.first-line-indent li { margin-left: 2em; } .for-image #write { padding-left: 8px; padding-right: 8px; } body.typora-export { padding-left: 30px; padding-right: 30px; } .typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; } .typora-export .task-list-item input { pointer-events: none; } @media screen and (max-width: 500px) { body.typora-export { padding-left: 0px; padding-right: 0px; } #write { padding-left: 20px; padding-right: 20px; } .CodeMirror-sizer { margin-left: 0px !important; } .CodeMirror-gutters { display: none !important; } } #write li > figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max-width: 100%; vertical-align: middle; image-orientation: from-image; } button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; } input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; } *, ::after, ::before { box-sizing: border-box; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; } p { line-height: inherit; } h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; } p { orphans: 4; } h1 { font-size: 2rem; } h2 { font-size: 1.8rem; } h3 { font-size: 1.6rem; } h4 { font-size: 1.4rem; } h5 { font-size: 1.2rem; } h6 { font-size: 1rem; } .md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; } .hidden { display: none; } .md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; } a { cursor: pointer; } sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; } #write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; } figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; } figure > table { margin: 0px; } tr { break-inside: avoid; break-after: auto; } thead { display: table-header-group; } table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; } table.md-table td { min-width: 32px; } .CodeMirror-gutters { border-right-width: 0px; background-color: inherit; } .CodeMirror-linenumber { } .CodeMirror { text-align: left; } .CodeMirror-placeholder { opacity: 0.3; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-lines { padding: 0px; } div.hr:focus { cursor: none; } #write pre { white-space: pre-wrap; } #write.fences-no-line-wrapping pre { white-space: pre; } #write pre.ty-contain-cm { white-space: normal; } .CodeMirror-gutters { margin-right: 4px; } .md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; } .md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; } #write .md-fences.mock-cm { white-space: pre-wrap; } .md-fences.md-fences-with-lineno { padding-left: 0px; } #write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; } .md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; } .CodeMirror-line, twitterwidget { break-inside: avoid; } .footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; } .footnotes + .footnotes { margin-top: 0px; } .md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; } li div { padding-top: 0px; } blockquote { margin: 1rem 0px; } li .mathjax-block, li p { margin: 0.5rem 0px; } li blockquote { margin: 1rem 0px; } li { margin: 0px; position: relative; } blockquote > :last-child { margin-bottom: 0px; } blockquote > :first-child, li > :first-child { margin-top: 0px; } .footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; } #write .footnote-line { white-space: pre-wrap; } @media print { body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; } #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; } .typora-export * { -webkit-print-color-adjust: exact; } .typora-export #write { break-after: avoid; } .typora-export #write::after { height: 0px; } .is-mac table { break-inside: avoid; } .typora-export-show-outline .typora-export-sidebar { display: none; } } .footnote-line { margin-top: 0.714em; font-size: 0.7em; } a img, img a { cursor: pointer; } pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; } p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; } #write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; } p > .md-image:only-child { display: inline-block; width: 100%; } #write .MathJax_Display { margin: 0.8em 0px 0px; } .md-math-block { width: 100%; } .md-math-block:not(:empty)::after { display: none; } .MathJax_ref { fill: currentcolor; } [contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; } .md-task-list-item { position: relative; list-style-type: none; } .task-list-item.md-task-list-item { padding-left: 0px; } .md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; } .math { font-size: 1rem; } .md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; } .md-toc-content { position: relative; margin-left: 0px; } .md-toc-content::after, .md-toc::after { display: none; } .md-toc-item { display: block; color: rgb(65, 131, 196); } .md-toc-item a { text-decoration: none; } .md-toc-inner:hover { text-decoration: underline; } .md-toc-inner { display: inline-block; cursor: pointer; } .md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; } .md-toc-h2 .md-toc-inner { margin-left: 2em; } .md-toc-h3 .md-toc-inner { margin-left: 4em; } .md-toc-h4 .md-toc-inner { margin-left: 6em; } .md-toc-h5 .md-toc-inner { margin-left: 8em; } .md-toc-h6 .md-toc-inner { margin-left: 10em; } @media screen and (max-width: 48em) { .md-toc-h3 .md-toc-inner { margin-left: 3.5em; } .md-toc-h4 .md-toc-inner { margin-left: 5em; } .md-toc-h5 .md-toc-inner { margin-left: 6.5em; } .md-toc-h6 .md-toc-inner { margin-left: 8em; } } a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; } .footnote-line a:not(.reversefootnote) { color: inherit; } .md-attr { display: none; } .md-fn-count::after { content: "."; } code, pre, samp, tt { font-family: var(--monospace); } kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; } .md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); } code { text-align: left; } a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; } .md-inline-math .MathJax_SVG .noError { display: none !important; } .html-for-mac .inline-math-svg .MathJax_SVG { vertical-align: 0.2px; } .md-fences-math .MathJax_SVG_Display, .md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: visible; display: block !important; } .MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; } .MathJax_SVG .MJX-monospace { font-family: var(--monospace); } .MathJax_SVG .MJX-sans-serif { font-family: sans-serif; } .MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; zoom: 90%; } #math-inline-preview-content { zoom: 1.1; } .MathJax_SVG * { transition: none; } .MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; margin-top: 0px !important; } .os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; } .md-diagram-panel > svg { max-width: 100%; } [lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; } [lang="mermaid"] .node text { font-size: 1rem; } table tr th { border-bottom-width: 0px; } video { max-width: 100%; display: block; margin: 0px auto; } iframe { max-width: 100%; width: 100%; border: none; } .highlight td, .highlight tr { border: 0px; } mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); } .md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; } .md-expand mark .md-meta { opacity: 0.3 !important; } mark .md-meta { color: rgb(0, 0, 0); } @media print { .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; } } .md-diagram-panel .messageText { stroke: none !important; } .md-diagram-panel .start-state { fill: var(--node-fill); } .md-diagram-panel .edgeLabel rect { opacity: 1 !important; } .md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); } .md-fences.md-fences-math { font-size: 1em; } .md-fences-math .MathJax_SVG_Display { margin-top: 8px; cursor: default; } .md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; } .md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; } .typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; } .typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; } .typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; } @media screen and (max-width: 1024px) { .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; } } @media screen and (max-width: 800px) { .typora-export-sidebar { display: none; } } .outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; } .outline-content ul { margin-top: 0px; margin-bottom: 0px; } .outline-content strong { font-weight: 400; } .outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; } .outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; } .outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; } .outline-expander:hover::before { content: ''; } .outline-h1 > .outline-item { padding-left: 0px; } .outline-h2 > .outline-item { padding-left: 1em; } .outline-h3 > .outline-item { padding-left: 2em; } .outline-h4 > .outline-item { padding-left: 3em; } .outline-h5 > .outline-item { padding-left: 4em; } .outline-h6 > .outline-item { padding-left: 5em; } .outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; } .outline-label:hover { text-decoration: underline; } .outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); } .outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; } .outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; } .outline-item-open > .outline-item > .outline-expander::before { content: ''; } .outline-children { display: none; } .info-panel-tab-wrapper { display: none; } .outline-item-open > .outline-children { display: block; } .typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; } .typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; } .typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; } .typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; } .typora-export-collapse-outline .outline-children { display: none; } .typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; } .typora-export-no-collapse-outline .outline-expander::before { content: "" !important; } .typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; } :root { --side-bar-bg-color: #fafafa; --control-text-color: #777; } @include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext); /* open-sans-regular - latin-ext_latin */ /* open-sans-italic - latin-ext_latin */ /* open-sans-700 - latin-ext_latin */ /* open-sans-700italic - latin-ext_latin */ html { font-size: 16px; } body { font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; color: rgb(51, 51, 51); line-height: 1.6; } #write { max-width: 860px; margin: 0 auto; padding: 30px; padding-bottom: 100px; } @media only screen and (min-width: 1400px) { #write { max-width: 1024px; } } @media only screen and (min-width: 1800px) { #write { max-width: 1200px; } } #write > ul:first-child, #write > ol:first-child{ margin-top: 30px; } a { color: #4183C4; } h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid #eee; } h2 { font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid #eee; } /*@media print { .typora-export h1, .typora-export h2 { border-bottom: none; padding-bottom: initial; } .typora-export h1::after, .typora-export h2::after { content: ""; display: block; height: 100px; margin-top: -96px; border-top: 1px solid #eee; } }*/ h3 { font-size: 1.5em; line-height: 1.43; } h4 { font-size: 1.25em; } h5 { font-size: 1em; } h6 { font-size: 1em; color: #777; } p, blockquote, ul, ol, dl, table{ margin: 0.8em 0; } li>ol, li>ul { margin: 0 0; } hr { height: 2px; padding: 0; margin: 16px 0; background-color: #e7e7e7; border: 0 none; overflow: hidden; box-sizing: content-box; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul:first-child, ol:first-child { margin-top: 0; } ul:last-child, ol:last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dfe2e5; padding: 0 15px; color: #777777; } blockquote blockquote { padding-right: 0; } table { padding: 0; word-break: initial; } table tr { border: 1px solid #dfe2e5; margin: 0; padding: 0; } table tr:nth-child(2n), thead { background-color: #f8f8f8; } table th { font-weight: bold; border: 1px solid #dfe2e5; border-bottom: 0; margin: 0; padding: 6px 13px; } table td { border: 1px solid #dfe2e5; margin: 0; padding: 6px 13px; } table th:first-child, table td:first-child { margin-top: 0; } table th:last-child, table td:last-child { margin-bottom: 0; } .CodeMirror-lines { padding-left: 4px; } .code-tooltip { box-shadow: 0 1px 1px 0 rgba(0,28,36,.3); border-top: 1px solid #eef2f2; } .md-fences, code, tt { border: 1px solid #e7eaed; background-color: #f8f8f8; border-radius: 3px; padding: 0; padding: 2px 4px 0px 4px; font-size: 0.9em; } code { background-color: #f3f4f4; padding: 0 2px 0 2px; } .md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; } .md-task-list-item > input { margin-left: -1.3em; } @media print { html { font-size: 13px; } table, pre { page-break-inside: avoid; } pre { word-wrap: break-word; } } .md-fences { background-color: #f8f8f8; } #write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: #f7f7f7; border: 0; border-radius: 3px; color: #777777; margin-top: 0 !important; } .mathjax-block>.code-tooltip { bottom: .375rem; } .md-mathjax-midline { background: #fafafa; } #write>h3.md-focus:before{ left: -1.5625rem; top: .375rem; } #write>h4.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h5.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h6.md-focus:before{ left: -1.5625rem; top: .285714286rem; } .md-image>.md-meta { /*border: 1px solid #ddd;*/ border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; } .md-tag { color: #a7a7a7; opacity: 1; } .md-toc { margin-top:20px; padding-bottom:20px; } .sidebar-tabs { border-bottom: none; } #typora-quick-open { border: 1px solid #ddd; background-color: #f8f8f8; } #typora-quick-open-item { background-color: #FAFAFA; border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; border-style: solid; border-width: 1px; } /** focus mode */ .on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); } header, .context-menu, .megamenu-content, footer{ font-family: "Segoe UI", "Arial", sans-serif; } .file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state{ visibility: visible; } .mac-seamless-mode #typora-sidebar { background-color: #fafafa; background-color: var(--side-bar-bg-color); } .md-lang { color: #b4654d; } /*.html-for-mac { --item-hover-bg-color: #E6F0FE; }*/ #md-notification .btn { border: 0; } .dropdown-menu .divider { border-color: #e5e5e5; opacity: 0.4; } .ty-preferences .window-content { background-color: #fafafa; } .ty-preferences .nav-group-item.active { color: white; background: #999; } .menu-item-container a.menu-style-btn { background-color: #f5f8fa; background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); } :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} 目录 技术概要:InterSystems API 管理器InterSystems API管理器是如何工作的?试一试!在 InterSystems IRIS 中设置 REST API 在 IAM 中为您的 REST API 创建服务在 IAM 中创建路由 从 REST 客户端调用您的 API添加速率限制插件添加您的 REST 规范到 IAM了解有关 InterSystems API Manager 的更多信息 技术概要:InterSystems API 管理器 本文档将向您介绍InterSystems API管理器(InterSystems API Manager ,IAM),解释了它的工作原理,并让您开始在自己的实例上探索它的功能。 InterSystems API管理器是如何工作的? InterSystems API管理器是 InterSystems IRIS®数据平台的一个组件,它允许您利用由 InterSystems IRIS 应用程序暴露或消费的微服务和 API。作为 InterSystems IRIS的 服务器和应用程序之间的 API 网关(gateway),API 管理器使您能够更有效地监视和控制服务器端 API 和客户端应用程序之间的调用流量。 要了解有关 InterSystems API管理器的更多信息,您可以观看这个概述视频。 试一试! InterSystems API管理器(InterSystems API Manager ,IAM)是与 InterSystems IRIS 实例分开安装的。要获得自己的 IAM 安装包,您可以从 InterSystems WRC 软件分发(Software Distribution)网站下载 ,或者联系您的 InterSystems 销售工程师。安装包包括一个脚本(iam-setup),用于设置 IAM 并将它与您的 InterSystems IRIS 实例连接。 这个练习假定您有 InterSystems IRIS 和 IAM 的实例,并且已经运行了安装脚本来连接它们。本练习使用 IAM 2.3 版本进行展示。 在 InterSystems IRIS 中设置 REST API 从位于 https://github.com/intersystems/FirstLook-IAM 的 GitHub 存储库中,将以下内容导入 InterSystems IRIS: /cls/cmAPI 包括使用 API 管理服务生成的三个类文件,以及一个coffeemaker对象定义: impl.cls disp.cls spec.cls coffeemaker.cls 要导入,请打开 InterSystems IRIS 管理门户(Management Portal),并导航到 Classes 页面(System Explorer(系统资源管理器) > Classes(类));如果您不在 USER 命名空间中,请使用左边的选择器来更改为它,如下图所示: 选择上面列出的四个类并点击 Import(导入)。这将 REST API 导入 InterSystems IRIS,同时导入相应的类,应用程序将使用这些类访问存储在数据库中的coffermakers集合。 /gbl/coffeemakers.gof。 通过进入管理门户(Management Portal),并点击 System Explorer(系统资源管理器)> Globals > Import(导入)来导入。查找 coffeemakers.gof。导入到 User.cmAPI.coffeemaker 模式。 接下来,设置一个 Web 应用程序(Web Application),指向您刚刚导入的 REST 类。Web 应用程序层为自定义和安全提供了额外的机会。在管理门户(Management Portal)中,选择 System Administration(系统管理) > Security(安全) > Applications(应用程序)> Web Applications(Web 应用程序)。点击 Create New Web Application(新建Web 应用程序) 并填写以下设置: Name(名称): /rest/coffeemakerapp Namespace(命名空间): USER Enable Application(启用应用程序):选中此复选框 Enable(启用):选择 REST Dispatch Class(分派类): cmAPI.disp 安全设置 - Allowed Authentication Methods(允许的身份认证方法): Unauthenticated ,Password 在 IAM 中为您的 REST API 创建服务 正如您在 IAM 概述视频中所看到的,在 IAM 工作流中,有三个主要组件在发挥作用------消费者(Consumers)、路由(Route)和服务(Service)。IAM 中的服务是为您存在于 InterSystems IRIS 中的 API 创建的。在这种情况下,我们将为您的coffeemaker API 创建一个服务。 您从 WRC 下载的 IAM 包还包括一个脚本(iam-test),用于设置示例服务和路由。如果您运行了这个脚本,您将能够查看 test-iris 服务。 我们将取得类似的结果,使用 IAM 门户添加您的Coffeemakers服务。 iam-setup.sh是用来启动 IAM 的,可以通过输入iam-setup.sh 脚本中指定的门户的 URL 来启动 IAM 管理门户(management portal)。默认情况下,URL 是: http://localhost:8002 选择 default Workspace(默认工作区)。如果默认工作区不可见,而且管理门户(Management Portal)似乎是空的,那么可能是您没有输入 iam-setup.sh 定义的确切 URL。 选择 API Gateway(API 网关) 中的 Services(服务),并选择 New Service(新的服务)。请按以下方式填写表格: Name(名称): 咖啡机服务(CoffeemakerService) 选择 Add using Protocol, Host and Path(添加使用协议、主机和路径) Protocol(协议): http Host(主机):[插入您的 InterSystems IRIS 实例的 IP 地址。为避免 DNS 问题,使用 IP 地址的数字形式。] Path(路径): /rest/coffeemakerapp Port(端口): [插入您的实例的 webserver 端口,默认为 52773,或者如果实例是在容器中,您已经映射到 web 服务器(webserver) 端口的主机端口] 不要选择"查看 6 个高级字段(View 6 Advanced Fields)"。 选择 Create(创建)。 一旦创建了服务,您就可以查看服务,并需要创建路由。 在 IAM 中创建路由 当您在查看服务时,选择 "添加路由(Add a Route)"。请按以下方式填写表格: Sevice(服务):此字段已正确地用服务的十六进制的 ID 初始化。 Name(名称): 可以留空 Protocols(协议):http Hosts(主机): 可以留空 Methods(方法):GET、POST、PUT、DELETE Paths(路径):select(选择) "+添加路径(Add Path)"并输入 /rest/coffeemakerapp Headers(标题): 可以留空 HTTPS Redirect Status Code(HTTPS 重定向状态代码): 426(这是默认值) Tags(标签): 可以留空 不要选择 "查看 4 个高级字段(View 4 Advanced Fields)"。 选择 Create(创建)。 一旦创建了路由,您将通过从 REST 客户端进行简单的 API 调用来测试您的路由和服务。 从 REST 客户端调用您的 API 使用 REST 客户端------可以使用Postman 或来自 Google Chrome 的高级 REST 客户端(Advanced REST Client)------在 InterSystems IRIS 中对您的咖啡机(Coffeemakers) API 进行一个简单的 API 调用。要做到这一点,创建一个请求 URL,其中包括您的 IAM 实例的 IP 地址和端口号,以及您的服务的路径和请求的端点。请务必使用用户名和密码授权您的请求。下面是一个示例;注意,默认情况下,IAM 处理 8000 端口上的代理请求。例如: POST http://localhost:8000/rest/coffeemakerapp/coffeemakers 一旦您成功地进行了调用,您可以导航回您的 IAM 仪表板(Dashboard),查看来自所进行的调用的统计数据和其他信息。从这个仪表板上,您可以看到许多不同的信息集,这些信息将帮助您监控和控制客户端应用程序和 InterSystems IRIS 内的服务之间的流量。 添加速率限制插件 有效地监测您的 API 流量是有益的,但仅限于使用该信息适当地控制和优化流量。IAM 使您能够使用一些不同的插件来提高您控制客户端和 API 之间流量的能力。 在 IAM 管理门户(Management Portal)中,选择 API Gateway(API 网关) 中的 Plugins(插件) ,并选择 New Plugin(新的插件)。在 Traffic Control(流量控制) 类别中,找到 Rate Limiting(速率限制) 插件,并选择 Enable(启用)。 在这个插件的配置屏幕上: 选择 Scoped(范围)。 在 Service(服务) 中选择咖啡机服务(CoffeeMakerService)。 试一试! 其他大部分字段保留它们的默认值,但将 Config.Limit By 设置为服务(Service),将 Config.Minute 设置为 5。 这将限制所有消费者每分钟只能调用 5 次服务中所有路由。 选择 Create(创建)。 您可以通过返回 REST 客户端并进行示例调用来测试这个速率限制插件。客户端超过限制后,它将得到一个 429 返回错误,并带有"超过 API 速率限制"的信息 添加您的 REST 规范到 IAM REST 开发的最佳实践方法是规范优先,因此很可能您已经有了自己的 REST 规范。对于这个练习,您可以使用您从 github 下载 FirstLook-IAM 存储库时,spec 目录下的 swagger_100419.json 文件。您也可以直接从 GitHub 存储库的 spec 文件夹中下载 JSON 规范。 https://github.com/intersystems/FirstLook-IAM/blob/master/spec/swagger_100419.json 注意: 有关记录和管理 REST API 规范的更多信息,请参见 Creating REST Services(《创建 REST 服务》)中的 Discovering and Documenting REST APIs(发现和记录 REST API)。 一旦下载,您就能将您的规范添加到 IAM 中: 从 IAM 管理门户(management portal),选择 Workspaces(工作区) 标签并选择默认工作区。 为咖啡机服务(CoffeemakerService)服务选择 View(查看)。 在 Documents(文档) 区域(面板的底部)选择 Add a document(添加一个文档)到这个服务。 点击下面的文件选择器文本框 Or upload a new spec instead...(或者上传一个新的规范代替...) ,然后选择您下载的 swagger_100419.json 文件。 您现在可以查看咖啡机服务(CoffeemakerService)的 OpenAPI 规范。外部开发者也可以访问这个规范,这允许他们开发对它的 REST 调用。由于 curl 命令没有指定正确的服务,所以 "试一试(Try it Out)"选项将无法工作。 了解有关 InterSystems API管理器 的更多信息 注意: 如果没有设置默认的开发门户(dev portal),选择 Set up Dev Portal(设置开发门户)。如果默认的开发门户(Dev Portal)被禁用,选择 Enable Developer Portal(启用开发门户)。它可能需要几分钟的时间来设置。 了解有关 InterSystems API Manager 的更多信息 InterSystems 提供了一些参考资料来了解有关 IAM 的更多信息: API Manager Introduction(《API Manager 介绍》) (演示) What is InterSystems API管理器?(《什么是 InterSystems API管理器?》)(视频) IAM Guide(《IAM 指南》) (文档) 如果您想了解有关如何开发咖啡机服务(CoffeemakerService) REST 服务的更多详细信息,请参见 《技术概要:在 InterSystems 产品中开发 REST 接口》。
文章
jieliang liu · 十月 27, 2021

IRIS 2021 技术文档 First Look 34 技术概要:InterSystems IRIS Native API for Python

技术概要:InterSystems IRIS Native API for Python 目录 技术概要: InterSystems IRIS Native API for Python 1 InterSystems IRIS 存储结构简介 1 探索 IRIS Native for Python 1 用前须知 2 安装 Native API 包 2 IRIS Native 应用程序 2 运行练习 3 确认管理门户(Management Portal)中的变更 3 了解有关 IRIS Native 的更多信息 3 技术概要:InterSystems IRIS Native API for Python 本技术概要(First Look)指南解释了如何使用 InterSystems IRIS Native 功能从 Python 应用程序访问 InterSystems IRIS® globals。IRIS Native 还允许您运行 ObjectScript 方法、函数和例程。在本文中,您将首先连接到 InterSystems IRIS。然后您将在 InterSystems IRIS 中设置和检索一个 global 节点的值,并在另一个 global 节点上进行迭代。您还将调用 InterSystems IRIS 类方法。所有这些活动都将在 Python 3 应用程序中执行。 为了让您体验 IRIS Native,而又不陷入细节的困境,本次探索特意设计得很简单。这些活动被设计成只使用默认设置和功能,这样您就可以熟悉功能的基本原理,而不必处理那些离题或过于复杂的细节。当您把 IRIS Native 引入您的生产系统时,您可能需要做一些不同的事情。请确保不要把这种对 IRIS Native 的探索与真实的情况相混淆! 本文档末尾提供的参考资料将使您对在生产中使用 IRIS Native 的情况有一个很好的了解。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 InterSystems IRIS 存储结构简介 InterSystems IRIS 提供了一种易于使用的方法来将数据存储在持久化多维数组中。global 是存储在物理 InterSystems IRIS 数据库中的命名多维数组。在应用程序中,globals 到物理数据库的映射基于当前命名空间,命名空间提供一个或多个物理数据库的逻辑统一视图。例如,要使用一个名为* ^Settings* 的 global 将值 "Red "与键 "Color "关联起来,请使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的为您的实例描述的程序打开 InterSystems 终端(InterSystems Terminal),并输入以下代码: set ^Settings("Color")="Red" 您可以利用 globals 的多维特性来定义一个更复杂的结构: set ^Settings( "Auto1 ", "Properties ", "Color ") = "Red " set ^Settings( "Auto1 ", "Properties ", "Model ") = "SUV " set ^Settings( "Auto2 ", "Owner ") = "Mo " set ^Settings( "Auto2 ", "Properties ", "Color ") = "Green " 有关 globals 的更多信息,请参见 Using Globals(《使用 globals》)。 探索 IRIS Native for Python 现在,您已经准备好实验 IRIS Native 了。下面的简短演示向您演示了如何在一个简单的 Python 应用程序中使用 IRIS Native。 想试试 InterSystems Native API for Python 的在线视频演示吗?请查看 Python QuickStart(Python 快速入门)! 探索 IRIS Native for Python 用前须知 要使用这个程序,您需要一个正在运行的 InterSystems IRIS 实例和一个使用 Python 3 和 PIP 实用程序以及您喜欢的 Python IDE 的系统。(在 Windows 系统中,确保 Python 解释器包含在您的 PATH 环境变量中)。您对 InterSystems IRIS 的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。使用同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 Python IDE 中的信息,将 Visual Studio 连接到您的 InterSystemsIRIS 实例。 安装 Native API 包 在运行示例 Python 程序之前,您需要使用 PIP 包管理器来安装 irisnative 包,您可以从 https://github.com/intersystems/quickstarts-python/tree/master/Solutions/nativeAPI_wheel 下载。 如果您的本地系统上安装了 InterSystems IRIS,wheel 文件已经安装在子目录 install-dir dev python 中,其中 install-dir 是 InterSystems IRIS 实例的安装目录, Python 3 包的名称 (.whl 文件) 包括 cp34。 要安装 wheel 文件,在命令行中输入命令 pip install irisnative-1.0.0 whl file,其中 irisnative-1.0.0 whl file 是您的 Python 版本和操作系统对应的 wheel 文件。例如,如果您在 Linux 上使用 Python 3,请使用 irisnative-1.0.0-cp34-abi3-linux_x86_64.whl。 IRIS Native 应用程序 现在您已经创建了项目,接下来您将创建一个小的应用程序,演示 Native API 的一些功能。 在您的 IDE 中,在 IRISNative 目录中创建一个新的源文件,将该文件保存为 IRISNative.py。 将以下代码粘贴到 IRISNative.py 中,将 InterSystems IRIS 实例的连接信息替换为 kwargs 中的值。您可以指定所示的 USER 命名空间,也可以选择在实例上创建的另一个命名空间: import irisnative # Modify connection info based on your environment ip = "127.0.0.1 " port = 1972 namespace = "USER " username = " _SYSTEM " password = "SYS " # create database connection and IRIS instance connection = irisnative.createConnection(ip,port,namespace,username,password) dbnative = irisnative.createIris(connection) print( " [1. Setting and getting a global ] ") # setting and getting a global # ObjectScript equivalent: set ^testglobal( "1 ") = 8888 dbnative.set(8888, "testglobal ", "1 ") # ObjectScript equivalent: set globalValue = $get( ^testglobal( "1 ")) globalValue = dbnative.get( "testglobal ", "1 ") print( "The value of testglobal is ", globalValue) print() print( " [2 Iterating over a global ] ") # modify global to iterate over # ObjectScript equivalent: set ^testglobal( "1 ") = 8888 # ObjectScript equivalent: set ^testglobal( "2 ") = 9999 dbnative.set(8888, "testglobal ", "1 ") dbnative.set(9999, "testglobal ", "2 ") Iter = dbnative.iterator( "testglobal ") print( "walk forwards ") 了解有关 IRIS Native 的更多信息 for subscript, value in Iter.items(): print( "subscript= {}, value={} ".format(subscript, value)) print() print( " [3. Calling a class method ] ") # calling a class method # ObjectScript equivalent: set returnValue = ##class(%Library.Utility).Date(5) returnValue = dbnative.classMethodValue( "%Library.Utility ", "Date ", 5) print(returnValue) # close connection connection.close() 示例代码分为三个部分: 第一部分展示了如何设置一个 global 的值以及稍后如何检索它。这部分里面执行的命令等同于 ObjectScript 的 SET 和 GET 命令。 第二部分展示了如何迭代 global 的子节点,类似于 ** $ORDER** ObjectScript 函数。 第三部分展示了如何使用 IRIS Native 从您的 Python 应用程序调用 ObjectScript 类方法。 注意: ObjectScript中的 Globals 以插入符号( ^)开头。在使用 InterSystems IRIS Native API 的 Python 应用程序中,这不是必需的。 运行练习 现在您已经准备好运行演示应用程序了。如果示例执行成功,您应该会看到带有示例代码结果的打印输出: [1. Setting and getting a global ] The value of testglobal(1) is 8888 [2.Iterating over a global ] walk forwards subscript=1, value=8888 subscript=2, value=9999 [3. Calling a class method ] Jan 30, 2018 确认管理门户(Management Portal)中的变更 接下来,使用以下程序在管理门户(Management Portal)中确认您的结果: 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中为您的实例描述的 URL,在浏览器中打开您的实例的管理门户(Management Portal)。 <span id="3_Learn_More_About_IRIS_Native" class="anchor"></span>如果您不在代码指定的命名空间中,请切换到该命名空间。 导航到 Globals 页面(System Explorer(系统资源管理器) > Globals)。您应该会看到示例代码中创建的 testglobal global。点击 View(查看)来查看其内容。您应该会看到 global 的两个节点: ^testglobal(1) = 8888 和 ^testglobal(2) = 9999。 了解有关 IRIS Native 的更多信息 有关 IRIS Native、globals 和 InterSystems IRIS 的更多信息,请参见:Using the Native API for Python(《使用 Native API for Python》) 了解有关 IRIS Native 的更多信息 Using Globals(《使用 Globals》)
文章
jieliang liu · 十月 26, 2021

IRIS 2021 技术文档 First Look 29 技术概要:LDAP 和 InterSystems 产品

技术概要:LDAP 和 InterSystems 产品 目录 技术概要: LDAP 和 InterSystems 产品 1 设置 LDAP 身份验证 1 选择 InterSystems IRIS 实例 1 定义 LDAP 配置 1 选择新的 LDAP 域作为默认值 2 启用 LDAP 身份验证 2 为 LDAP 服务器安装安全证书 3 探索 LDAP 用户和组 4 User1: 操作员 4 User2: 管理者 5 User3: 开发者 5 自动创建用户 6 了解有关 LDAP 和安全的更多信息 6 技术概要:LDAP 和 InterSystems 产品 InterSystems IRIS®数据平台可以与 LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)服务器集成,从而可以无缝地使用这种流行技术对用户进行身份验证。通过 LDAP 提供授权也很容易。 当用户尝试登录 InterSystems IRIS 时,用户名和密码会被发送到 LDAP 服务器,以验证该用户是否存在。一旦用户的身份得到验证,LDAP 服务器就会向 InterSystems IRIS 发送关于用户属于哪些组的信息。这些组与 InterSystems IRIS 中的角色相对应,这些角色控制用户被授权执行什么操作,以及是否可以读取或写入内容。通过这种方式,InterSystems IRIS 在其安全策略的身份验证和授权方面都使用了 LDAP 技术。 按照本指南中的步骤,您可以连接到 LDAP 服务器,并探索它如何影响 InterSystems IRIS 中的安全。在这些练习中,您将配置 InterSystems IRIS 以与 Windows 活动目录(Active Directory)服务器集成。虽然也支持其他的 LDAP 服务器,但本文主要介绍如何使用活动目录(Active Directory)进行 LDAP 身份验证和授权。 要浏览所有的技术概要(First Look),包括下面描述的可以在免费的社区版(Community Edition)实例上执行的其他内容,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 设置 LDAP 身份验证 在以 LDAP 用户登录并在 InterSystems IRIS 中探索基于 LDAP 的安全之前,需要完成以下操作: 选择 InterSystems IRIS 实例 定义 LDAP 配置 选择 LDAP 域作为默认值 在 InterSystems IRIS 中启用 LDAP 身份验证 为 LDAP 服务器安装安全证书 选择 InterSystems IRIS 实例 要使用该程序,您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。 定义 LDAP 配置 InterSystems IRIS 使用 LDAP 配置来定义连接到 LDAP 服务器和搜索用户所需的信息。要创建和定义新的 LDAP 配置: 设置 LDAP 身份验证 在浏览器中打开您的实例的管理门户(Management Portal)。要使用的 URL 取决于您选择的实例类型;有关确定正确的 URL 的信息,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)。 进入 Security LDAP Configurations(安全 LDAP 配置) 页面 (System Administration(系统管理) > Security(安全) > System Security(系统安全) > LDAP Configurations(LDAP 配置))。 点击 Create New LDAP configuration(创建新 LDAP 配置)。 在 Name(名称)字段中,输入 irisldap.com。 选择 Enabled(已启用) 复选框。 选择 LDAP server is a Windows Active Directory server(LDAP 服务器是一个 Windows 活动目录(Active Directory) 服务器) 复选框。 定义以下字段: +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | 字段 | > 内容 | +=================================================================+===========================================================================+ | LDAP domain name(LDAP 域名) (仅限 Windows) | > irisldap.intersystems.com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP host names(LDAP 主机名) | > irisldapdc1.irisldap.intersystems.com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP username to use for searches(用于搜索的 LDAP 用户名) | - (Windows) sidLDAPQuery | | | | | | - (UNIX®) | | | | | | > CN=sidLDAPQuery,CN=Users,DC=irisldap,DC=intersystems,DC=com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP username password(LDAP 用户名密码) | > 选择 Enter New Password(输入新密码), 然后输入密码为 Cach3L3arning | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP Base DN to use for searches(用于搜索的 LDAP 基础 DN) | > DC=irisldap,DC=intersystems,DC=com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP Unique search attribute(LDAP 独特的搜索属性) | > sAMAccountName | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ 选择 Use TLS/SSL encryption for LDAP sessions(将 TLS/SSL 加密用于 LDAP 会话)复选框。 选择 Use LDAP Groups for Roles/Routine/Namespace(将 LDAP 组用于角色/路由/命名空间)复选框。 选择 Allow Universal group Authorization(允许通用组授权)复选框。 点击 Save(保存)。 选择新的 LDAP 域作为默认值 一旦定义了 LDAP 服务器的 LDAP 配置,您需要将新的 LDAP 配置设置为默认的 LDAP 域。要将 LDAP 服务器设置为默认服务器: 从管理门户(Management Portal)主页,进入 System-wide Security Parameters(全系统安全参数) 页面 (System Administration(系统管理) >**Security(安全) > System Security(系统安全) > System-wide Security Parameters(全系统安全参数)**)。 从 Default security domain(默认安全域)下拉列表中选择 irisldap.com。 点击 Save(保存)。 启用 LDAP 身份验证 使用 LDAP 服务器只是 InterSystems IRIS 中可用的一种身份验证方法。不仅必须为 InterSystems IRIS 的整个实例启用 LDAP 身份验证,而且需要由 LDAP 用户访问的 InterSystems IRIS 的每个组件也必须启用 LDAP 身份验证。以下程序为实例和 InterSystems IRIS 安全所需的那些组件启用 LDAP 身份验证: 设置 LDAP 身份验证 从管理门户(Management Portal)主页,进入 Authentication/Web Session Options(身份验证/Web 会话选项) 页面(System Administration(系统管理)> Security(安全) > System Security(系统安全) > Authentication/Web Session Options(身份验证/Web 会话选项))。 选择 Allow LDAP authentication(允许 LDAP 身份验证)复选框。 点击 Save(保存)。 从管理门户(Management Portal)主页,进入 Web Applications(Web 应用程序)页面 (System Administration(系统管理) > Security(安全) > Applications(应用程序) > Web Applications(Web 应用程序))。 在这个页面上,您将为您在 InterSystems IRIS 中将要访问的管理门户(Management Portal)部分启用 LDAP 授权。因为管理门户(Management Portal)的其他部分没有启用 LDAP 授权,如果您试图探索这些其他部分,可能会被要求登录。 点击 /csp/sys 来显示用于配置 web 应用程序的页面。 在 Security Settings(安全设置) 部分,在 Allowed Authentication Methods(允许的身份验证方法)字段中选择 LDAP 复选框。 点击 Save(保存)。 一旦设置被保存,点击 Cancel(取消)以返回到 Web Applications(Web 应用程序)页面。 点击 /csp/sys/sec。这个 web 应用程序包含管理门户(Management Portal)的安全页面。 在 Security Settings(安全设置)部分,在 Allowed Authentication Methods(允许的身份验证方法)字段中选择 LDAP 复选框。 点击 Save(保存)。 一旦设置被保存,点击 Cancel(取消)以返回到 Web Applications(Web 应用程序) 页面。 点击 /csp/sys/op。这个 web 应用程序包含管理门户(Management Portal)的操作页面。 <span id="1.5_Installing_a_Security_Certificate_fo" class="anchor"></span>在 Security Settings(安全设置) 部分,在 Allowed Authentication Methods(允许的身份验证方法)字段中选择 LDAP 复选框。 点击 Save(保存)。 为 LDAP 服务器安装安全证书 LDAP 服务器采用 TLS 进行安全保护,因此您需要安装安全证书才能成功访问服务器。在将其标识为安全证书之前,您将创建一个包含所需证书内容的 .cer 文件。 创建 .cer 文件 要创建将作为安全证书安装的文件: 打开一个文本编辑器,如记事本,并创建一个新文件。 复制以下所有内容并将其粘贴到文本编辑器中的新文件中。新文件应该以 -----BEGIN CERTIFICATE-----开头,并以-----END CERTIFICATE-----结尾。 -----BEGIN CERTIFICATE----- MIIDuTCCAqGgAwIBAgIQO5hG2uC7G7ZBxcXt/J+z3TANBgkqhkiG9w0BAQsFADBv MRMwEQYKCZImiZPyLGQBGRYDY29tMRwwGgYKCZImiZPyLGQBGRYMaW50ZXJzeXN0 ZW1zMRgwFgYKCZImiZPyLGQBGRYIaXJpc2xkYXAxIDAeBgNVBAMTF2lyaXNsZGFw LUlSSVNMREFQREMxLUNBMB4XDTE4MDQwOTE0MDUzMloXDTIzMDQwOTE0MTUzMlow bzETMBEGCgmSJomT8ixkARkWA2NvbTEcMBoGCgmSJomT8ixkARkWDGludGVyc3lz dGVtczEYMBYGCgmSJomT8ixkARkWCGlyaXNsZGFwMSAwHgYDVQQDExdpcmlzbGRh cC1JUklTTERBUERDMS1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AL/aNDJJNbzGh6tXG8+hmEEplb80UQMcIhLvoanz/RKKZXBBY68rO5pkYUwn/24g pryGy0OUjA997KKol5rdbXWzK7vUMuVSp0atw1m4vF9hmp1bpKBC60OXmV39Fqar ej1dkRl0ZXOmCexP8JqTyNwhpOLXvazzzvsNRr4ts9u1m6y9kFYecu4PRqtFCgoC T6rbgqz1Ew3VrhQHi0HWvq1sR2CngxdyG8AnlSo6nz3X/IrTwrw5lauNLfpsRda5 D5YfUpxYeqpONSUB650u9bC0l5eRWe8kS33Xr+u5Odkhy087I/zN+GK7xMGzxYMR OWNINIGRvlLuDRshKQl4gP0CAwEAAaNRME8wCwYDVR0PBAQDAgGGMA8GA1UdEwEB /wQFMAMBAf8wHQYDVR0OBBYEFM3Ofv4R/zkEgHkp4ayvTkAvxJikMBAGCSsGAQQB gjcVAQQDAgEAMA0GCSqGSIb3DQEBCwUAA4IBAQC8hhvc/+WsDeipNezBo+ovum2z 7q0fStr73Tj84cDGSyCmT2Q/h0qFvkfjtRd8AUBdG0qjhIB4VLVyWmrWDl1jAUcr 3AzygfO6UZjNRT+4c8r8R2xOhE3wJEJWibzXD9bPCtCkhYNJT6bi5PSRgUq+r9GU 探索 LDAP 用户和组 IHnAUmaQa+K+kNEpAvBfIeQ2ox9NPbtUfj/fswKpubWzZZc2udeU8SQLacl6tZMA tXgZPT6lQfoZU2WmDG1EnoC4Ji1++Sf6Ho2i6kxg1m6geyOPSsGPdsAVjYCqCjuZ pxjAsfZXV2juLyTBM51rrmV/Rqfougnikh4zhFRBrOHtMP71ZxCptMVz3RHe -----END CERTIFICATE----- 在您可以访问的目录中将该文件另存为 irisldap.cer。 在 Windows 上安装安全证书 如果您在 Windows 上运行 InterSystems IRIS,请完成以下步骤来完成安装您所创建的安全证书的过程。 使用 Windows 资源管理器(Explorer),双击在您保存文件的目录中的安全文件 irisldap.cer。 点击 Install Certificate(安装证书)。 选择 Local Machine(本地机器) 并点击 Next(下一步)。 点击 Yes(是) 以允许对您的设备进行更改。 选择 Place all certificates in the following store(将所有证书放入以下存储区)并点击 Browse(浏览)。 选择 Trusted Root Certification Authorities(受信任的根证书颁发机构)并点击 OK(确定)。 点击 Next(下一步)。 点击 Finish(完成)。 在 UNIX®上安装安全证书 如果您在 UNIX®上运行 InterSystems IRIS,请完成以下步骤来完成安装您所创建的安全证书的过程。 以 _system 用户身份登录管理门户(Management Portal)时,进入 Security LDAP Configurations(安全 LDAP 配置) 页面 (System Administration(系统管理) > Security(安全) > System Security(系统安全) > LDAP Configurations(LDAP 配置))。 从 LDAP 配置的列表中点击 irisldap.com。 在 TLS/SSL certificate file(TLS/SSL 证书文件)字段中,输入 irisldap.cer 的路径和文件名,这是您创建并保存的文件。 探索 LDAP 用户和组 现在您已经配置了您的 LDAP 连接并启用了 LDAP 身份验证,您可以使用 LDAP 服务器来登录 InterSystems IRIS。LDAP 服务器包含三个用户:user1、user2 和 user3。user1 属于 intersystems-Role-%Operator 组,user2 属于 intersystems-Role-%Manager 组,user3 属于 intersystems-Role-%Developer 组。每个组都授予属于 InterSystems IRIS 中相应角色的权限。例如,当 user1 通过 LDAP 服务器的身份验证成功时,将为其分配 %Operator 角色。 在本教程中,您将以所有三个用户的身份登录到 InterSystems IRIS,并根据与用户关联的角色探索可用的操作。当您作为一个有效的 LDAP 用户登录到 InterSystems IRIS 时,InterSystems IRIS 会自动创建用户,而不需要您事先手动添加用户。 User1: 操作员 要以 user1 的身份登录并探索 InterSystems IRIS: 如果您目前已登录到 InterSystems IRIS,请点击管理门户(Management Portal)左上角的 Logout(退出) 链接。 探索 LDAP 用户和组 使用以下凭证登录 InterSystems IRIS: 用户名:user1 密码:Password1 user1 是 intersystems-Role-%Operator 组的成员。基于这个组,当 user1 通过身份验证时,他们会被自动授予与 InterSystems IRIS 中 %Operator 角色相关的权限。 从管理门户(Management Portal)主页,进入 Databases(数据库) 页面 (System Operation(系统操作) > Databases(数据库))。user1 可以访问这个页面,因为他们已经被 LDAP 服务器授权,可以和与 %Operator 角色关联的页面进行交互。 在管理门户(Management Portal)主页上,请注意 System Administration(系统管理) 菜单已被禁用。 user1 不能访问此菜单,因为 %Operator 角色不包含适当的权限。 User2: 管理者 要以 user2 的身份登录并探索 InterSystems IRIS: 点击管理门户(Management Portal)左上角的 Logout(退出) 链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user2 密码:Password2 user2 是 intersystems-Role-%Manager 组的成员。基于这个组,当 user2 通过身份验证时,他们会被自动授予与 %Manager 角色相关的权限。正如您将看到的,这些权限包括访问 user1 无法看到的页面。 从管理门户(Management Portal)主页,进入 Users(用户) 页面 (System Administration(系统管理) > Security(安全) > Users(用户))。请记住,user1 不能访问 System Administration(系统管理) 菜单。 从用户列表中点击 user1。 点击 Roles(角色) 标签。 请注意,%Operator 是分配给 user1 的唯一角色。 点击 Cancel(取消) 以返回到 Users(用户) 页面。 请注意,在用户列表中没有 user3 的条目。该用户将在 user3 登录时自动创建,此时 InterSystems IRIS 使用 LDAP 服务器对用户进行身份验证。 User3: 开发者 要以 user3 的身份登录并探索 InterSystems IRIS: 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user3 密码:Password3 user3 是 intersystems-Role-%Developer 组的成员。基于这个组,当 user3 通过身份验证时,他们会被自动授予与 %Developer 角色相关的权限。 请注意,该用户可以访问 System Explorer(系统资源管理器)菜单,而不是 System Operation(系统操作)和 System Administration(系统管理)菜单。您可以看出,分配给 user3 的 %Developer 角色与分配给 了解有关 LDAP 和安全的更多信息 user1 和 user2 的角色具有不同的权限。这可以防止 user3 看到自己的用户配置文件,因为 Users(用户)页面是在 System Administration(系统管理)菜单下。 自动创建用户 您已经登录到 InterSystems IRIS,但没有先创建新用户。当在 LDAP 服务器上发现这些用户时,InterSystems IRIS 会自动创建这些用户。下面的程序演示了这个过程: 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user2 密码:Password2 请记住,user2 拥有 %Manager 角色。 从管理门户(Management Portal)主页,进入 Users(用户) 页面 (System Administration(系统管理) > Security(安全) > Users(用户))。 在列表中找到 user3 并点击行中的 Delete(删除)。 此时,拥有 %Developer 角色的 user3 在 InterSystems IRIS 中不复存在。 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user3 密码:Password3 因为 user3 仍然存在于 LDAP 服务器上,所以即使您刚刚在 InterSystems IRIS 中删除了用户帐户,您也能够以 user3 的身份重新登录到 InterSystems IRIS。 如果需要,您可以重新登录 InterSystems IRIS,以确认 user3 现在是一个用户。 a. 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 b. 使用以下凭证登录 InterSystems IRIS: 用户名:user2 密码:Password2 c. 从管理门户(Management Portal)主页,进入 System Administration(系统管理) > Security(安全) > Users(用户)。user3 现在在列表中,尽管您之前删除了该用户账户。 了解有关 LDAP 和安全的更多信息 您可以使用以下参考资料来了解有关 LDAP 和其他安全概念的更多信息。 有关在 InterSystems IRIS 中使用 LDAP 的详细信息,请参见 LDAP Guide(《LDAP 指南》)。 有关 InterSystems IRIS 中基于角色的安全的介绍,请参见 First Look:Role-Based Access Control(《技术概要:基于角色的访问控制》)。
文章
jieliang liu · 十月 26, 2021

IRIS 2021 技术文档 First Look 24 技术概要:容器中的 InterSystems 产品

本技术概要(First Look)通过重点概述和基本的实践示例,向您介绍在 InterSystems IRIS®数据平台上使用容器(Container)的基本原理。您将了解容器的目的、重要性和好处,以及 InterSystems 如何实现它们的具体细节。 有关 Docker 容器和 InterSystems IRIS 的完整文档,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》),以及 InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)的 ICM Overview(ICM 概述)章节。Learn More About InterSystems IRIS in Containers(了解容器中的 InterSystems IRIS 的更多信息)部分提供了到其他参考资料的链接。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 为什么是容器(Container)? 容器(Container)将应用程序打包成独立于平台、完全可移植的运行时解决方案(runtime solution),满足所有需求,但却隔离于任何依赖项(dependency)。具体来说,Docker 容器无处不在。因为所有主要的公共云基础设施即服务(Infrastructure as a Service,IaaS)供应商都支持 Docker,企业可以通过使用容器并让云供应商处理基础设施来降低成本和复杂性。 容器带来了以下所有的好处: 容器干净地划分代码和数据,提供完全分离的关注点,应用程序可轻松部署和升级。 容器是非常高效的;容器中的应用程序只包含运行它所需的元素(element),并使其能够访问所需的连接、服务和接口,而且容器作为单个进程运行,所占用的内存并不比任何其他可执行文件多。 容器支持应用程序在不同环境之间的清洁移动(clean movement)——例如,从开发到测试,再到生产——从而减少具有不同目标的部门之间的典型过程和管理冲突。开发人员可以专注于最新的代码和库(library),质量开发人员(quality developers)专注于测试和缺陷描述,运营工程师专注于整体解决方案的基础设施,包括网络、高可用性、数据持久性(data durability)等等。 容器提供了企业对业务和技术进行变革所需的敏捷性、灵活性和可重复性。容器将应用供应过程(包括构建阶段)与运行过程明确分开,企业可以采用统一的应用程序交付方法,包括更敏捷的交付方法(DevOps)和架构(微服务)。 这些优势使容器成为应用程序的天然构件块,推动应用程序交付和部署方法变得更简单、更快速、更可重复、更强大。 容器中的 InterSystems IRIS 因为容器只打包运行容器化应用程序所需的元素,并在本地执行应用程序,所以它提供标准的、易于理解的应用程序配置、行为和访问。如果您对在 Linux 上运行的 InterSystems IRIS 有经验,那么基于 Linux 的 InterSystems IRIS 容器在什么物理、虚拟或云系统和操作系统平台上运行并不重要;您以相同的方式与它们进行交互,就像在 Linux 系统上运行传统的 InterSystems IRIS 实例一样。 下面介绍 InterSystems IRIS 在如何使用容器方面的不同。 InterSystems 提供的映像(InterSystems-provided images)——容器映像(container image)是可执行包,而容器是映像(image)的运行时实例 (runtime instance)——即映像(image)在执行时在内存中变成的实例。InterSystems 提供包含完整安装的 InterSystems IRIS 实例的映像(image),以及其他相关映像(image)。有关 InterSystems 映像(image)的更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Using InterSystems IRIS Images(使用 InterSystems IRIS 映像)。 在本文档的实践体验中,您将从 InterSystems 提供的 InterSystems IRIS 映像(image)中创建并启动一个容器。 Iris-main 程序(iris-main program)——iris-main 程序使 InterSystems IRIS 和其他产品能够满足在 Docker 容器中运行的应用程序的要求。入口点应用程序(entrypoint application),即容器启动时启动的主进程,需要阻塞(block)——即等待(wait),直到其工作完成,但启动 InterSystems IRIS 的命令并不作为一个阻塞进程(blocking process)运行。iris-main 程序通过启动 InterSystems IRIS 来解决这个问题,然后继续作为阻塞入口点应用程序(blocking entrypoint application)运行。有关 iris-main 的更多信息,请参见在 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 The iris-main Program(iris-main 程序)。 该程序还提供了许多选项,以帮助调整 InterSystems IRIS 在容器中的行为;您将在本文档的实践体验中使用一些 iris-main 选项。 持久化 %SYS 功能(durable %SYS feature)——因为容器化的应用程序与主机环境隔离,所以它不会写入持久化数据(persist data);当容器被移除并被新的容器取代时,它在容器内写入的任何内容都会丢失。因此,容器化应用部署的一个重要方面是安排数据存储在容器之外,并提供给其他和未来的容器使用。 当 InterSystems IRIS 在容器中运行时,持久化 %SYS 功能(The durable %SYS feature)能够持久地存储特定于实例的数据——如用户定义、审计记录以及日志、日记和 WIJ 文件——允许一个实例跨越多个容器。例如,如果您使用持久化 %SYS 运行 InterSystems IRIS 容器,您可以通过停止原始容器(the original container)并运行使用旧容器创建的特定于实例的数据(instance-specific data)的新容器来升级实例。 您将在本文档的实践体验中探索持久化 %SYS (durable %SYS)功能。有关持久化 %SYS(durable %SYS) 的详细信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Durable %SYS for Persistent Instance Data(持久化 %SYS 的持久化实例数据)。 重要提示: InterSystems 的容器映像符合开放容器标准(Open Container Initiative,OCI)规范,并在 Docker 企业版(Enterprise Edition)引擎上使用广泛流行的容器 Ubuntu 操作系统构建,该引擎完全支持 OCI 标准,并允许映像在 Docker Hub 注册表中认证和展示。因此,InterSystems 映像在任何基于 Linux 操作系统的符合 OCI 标准的运行时引擎上都得到支持,无论是在自有云还是在公共云中。 InterSystems 云管理器(InterSystems Cloud Manager,ICM)在其提供的云基础设施以及现有的虚拟和物理基础设施上提供 InterSystems IRIS 容器和其他容器的自动部署。有关使用 ICM 部署容器化的 InterSystems IRIS 实例的更多信息,请参见 First Look:InterSystems Cloud Manager(《技术概要:InterSystems 云管理器》) 和 InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)。 3. 下载 InterSystems IRIS 映像(Image) 要使来自 InterSystemsInterSystems IRIS 映像(image)可用于本实践,您必须将映像(image)下载到您正在使用的系统中。以下替代方案描述了您可以或可能可以使用的 InterSystems IRIS 映像(image)。 您可以使用来自 InterSystems 容器注册表(InterSystems Container Registry,ICR)的 InterSystems IRIS 社区版(Community Edition)映像(image),该映像(image)包含可从 InterSystems 获得的所有映像(image)的存储库,如 Using the InterSystems Container Registry(《使用 InterSystems 容器注册表》)中所述。您也可以从 Docker Store 的 InterSystems IRIS 数据平台页面下载社区版(Community Edition)映像(image)。 InterSystems IRIS 社区版(Community Edition)有一个免费的内置 13个月的许可证(和一些功能限制);如果您在这次实践中使用社区版(Community Edition),您就不需要提供下一步(Add the License Key to the External Storage Location(添加许可证密钥到外部存储位置))中所述的许可证密钥。更多信息,请参见 Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的 Deploy InterSystems IRIS Community Edition on Your Own System(在您自己的系统上部署 InterSystems IRIS 社区版)。 注意: 另一个选择是在 GCP、AWS 或 Azure 上提供一个承载运行中的 InterSystems IRIS 社区版(Community Edition)容器的云节点;更多信息,请参见 Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的 Deploy InterSystems IRIS Community Edition on a Cloud Node(在云节点上部署 InterSystems IRIS 社区版)。如果您在这个练习中使用社区版(Community Edition)的云节点,您可以跳过接下来的两个步骤,并跳转到 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交)。 如果您是 InterSystems 客户,您可以使用 InterSystems 容器注册表(InterSystems Container Registry,ICR)发布的 InterSystems IRIS 映像(image)。Using the InterSystems Container Registry(使用 InterSystems 容器注册表)列出了 IRC 提供的 InterSystems IRIS 映像(image),并解释了如何使用您的 WRC 凭证对注册表进行身份验证,以便您下载。 您的企业可能有一个私有映像(image)注册表,其中包括一个或多个 InterSystems IRIS 映像(image)。如果是这样,请获取您需要的映像(image)的注册表、存储库和标签的位置,以及访问所需的凭证。 当您确定了要下载的注册表和需要的凭证(如果有)后,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品 》)中的 Downloadingthe InterSystems IRIS Image(下载 InterSystems IRIS 映像),了解下载 InterSystems IRIS 映像(image)的说明。 为了简单起见,这些说明假定您正在使用的映像(image)是 intersystems/iris:2021.1.0.205.0。 4. 添加许可证密钥到外部存储位置 与任何 InterSystems IRIS 实例一样,在容器中运行的实例需要一个许可证密钥(通常称为 iris.key)。 从 Docker Store 获得的 InterSystems IRIS 社区版(Community Edition)映像(在上一节中进行了描述)带有一个免费的内置临时许可证。然而,一般来说,许可证密钥没有也不能包含在 InterSystems IRIS 容器映像(container image)中,而是必须在容器启动后复制到容器中,以便激活运行在其中的 InterSystems IRIS 实例。iris-main 程序为此提供了一个选项,但它要求您把许可证密钥放在一个作为外部 volume 挂载的存储位置;下一节提供了使用说明。要了解有关 InterSystems IRIS 容器的许可证密钥的更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 License Keys for InterSystems IRIS Containers(InterSystems IRIS 容器的许可证密钥)。 将您的 InterSystems IRIS 许可证密钥文件 iris.key 复制到外部存储位置。 5. 从 InterSystems IRIS 映像(Image)运行容器 一旦您在本地机器上使 InterSystems IRIS 映像(image)可用,确定了外部存储位置并在其上放置了许可证密钥,您就可以使用 docker run 命令来创建和启动容器了。Docker run 命令实际上结合了三个独立的命令,如下所示: docker pull — 如果本地不存在映像(image),则下载一个。 docker create — 从映像(image)中创建一个容器。 docker start — 启动容器。 这些命令中的每一个都是单独有用的,在不同的背景下有不同的用途。更多信息,请参见 Docker 文档中的Docker run reference(Docker 运行参考资料) 。 下面是一个 docker run 命令的示例;所附文本对所有选项都作了解释。请注意,docker run 命令的选项出现在命令行中映像(image)规范之前,而 InterSystems iris-main 程序的选项(请参见 InterSystems IRIS in Containers(《容器中的 InterSystems IRIS》))出现在之后。在这种情况下,作为 docker run 一部分的 pull 命令不需要运行,因为您已经下载了您想使用的 iris 映像(image)。 docker run --name iris --detach --publish 52773:52773 --volume /nethome/pmartinez/iris_external:/external intersystems/iris:2021.1.0.205.0 --key /external/iris.key --name 容器名称(container name) 指定容器的名称,您可以在其他 Docker 命令中用它来引用该容器,例如,当您想停止该容器时,使用 docker stop container name 。 --detach 在后台运行容器(并显示容器的唯一 ID)。 --Publish 主机端口:容器端口(host_port:container_port) 将容器内的端口发布到主机上的端口,这样容器外(在主机上或其他机器上)的实体就可以与容器内的程序联系。例如,InterSystems IRIS 实例的管理门户(Management Portal)是通过实例的 Web 服务器端口(默认为 52773)访问的。如果容器内的这个端口发布到主机上的端口,那么可以使用主机的端口将实例的管理门户(Management Portal)加载到浏览器中。 --volume 外部存储路径:内部 volume(external_storage_path:internal_volume) 挂载容器可访问的外部存储位置作为容器内部的存储 volume。有关哪些存储位置可以以这种方式挂载以及可能需要的 Docker 配置的信息,请参见 Docker 文档中的 Use Volumes(使用 Volumes ) 。 重要提示: InterSystems 不支持在 InterSystems IRIS 容器中把 NFS 位置作为外部 volume 挂载。 存储库/映像:标签(repository/image:tag) 指定要提取并用于创建容器的映像(请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像))。使用 docker images 命令来列出可用的映像(image),并确保您指定的是正确的映像(image)。 --Key 许可证密钥路径(license_key_path) iris-main 选项,它标识了要安装在容器实例中的 InterSystems IRIS 许可证密钥;这个位置必须是在一个挂载的 volume 上。 使用前面的示例和说明来构建您自己的 docker run 命令,并在命令行上执行。当命令完成后,使用 docker ps 命令可以在列表中看到您的容器,状态为 Up。 试一试! 创建您自己的基于 InterSystems IRIS 的容器 $ docker run --name iris --detach --publish 52773:52773 --volume /nethome/pmartinez/iris_external:/external intersystems/iris:2021.1.0.205.0 --key /external/iris.key 426d4a511d6746d89ec2a24cf93b29aa546ea696b479a52210d37da4c6d04883 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS 426d4a511d67 intersystems/iris:2021.1.0.205.0 "/iris-main --key ..." 5 seconds ago Up 3 seconds PORTS NAMES 0.0.0.0:52773->52773/tcp iris 注意: InterSystems IRIS 社区版(Community Edition)映像(请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像))不需要--key 选项 ,该映像附带一个免费的内置许可证。 如果映像尚未在本地存在,但在您组织的存储库中——请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像),Docker 会在创建和启动容器之前拉取(下载)该映像(image)。 如示例所示,创建容器后,Docker 输出 UUID 长标识符(long identifier); 前 12 个字符组成 UUID 短标识符(short identifier),用于标识其他输出中的容器,例如来自 docker ps 命令的容器。 6.更改实例并将容器作为新映像(Image)提交 当您更改容器内运行的程序时,您可以使用 docker commit 命令从容器中创建一个新映像(image)。这个新映像(image)与您创建容器的原始映像(image)相同,但包括您对容器所作的更改。要了解其工作原理,请遵循以下步骤: 打开容器中 InterSystems IRIS 实例的管理门户(Management Portal)。实例的管理门户(Management Portal)的 URL 包含了实例的主机标识符和 web 服务器端口号 。 主机标识符是运行容器的系统的主机名或 IP 地址;如果您的浏览器与容器运行在同一个系统上,则可以使用 localhost。 Web 服务器端口号是您在使用 docker run 启动容器时发布的实例的 web 服务器端口号,即 52773 的主机端口号。假设您包含了--publish 52773:52773,正如上一节末尾的示例命令中提供的那样,web 服务器端口号是 52773。 例如,在容器主机上,Web 服务器端口为 52773,管理门户(Management Portal)的 URL 将是 http://localhost:52773/csp/sys/%25CSP.Portal.Home.zen。 使用预定义用户帐户之一登录,例如 _SYSTEM,其默认密码是 SYS(请参见 Predefined User Accounts(预定义用户账户))。出于安全考虑,在第一次登录(使用管理门户(Management Portal)或 iris terminal 命令)到容器化的 InterSystems IRIS 实例上的任何预定义账户时,系统会立即提示您更改密码。 注意: 有关更改预定义帐户(强烈建议在生产中这样做)的默认密码(包括在脚本和自动部署中)的更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Authentication and Passwords (身份验证和密码)。 从主页上,选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Namespaces(命名空间) 来显示 Namespaces(名称空间) 页面,然后点击 Create New Namespace(创建新的命名空间) 按钮来显示 New Namespace(新的命名空间) 页面。 创建名为 USER2 的命名空间,方法是在 Name of the namespace box(命名空间框的名称)中输入 USER2,从 Copy from 下拉菜单中选择 USER,清除 Enable namespace for interoperability productions(为互操作性产品启用命名空间) 复选框并确认,点击 Save(保存) 按钮,最后确认您想要复制所有属性和映射。 然后点击 Copy Namespace Mappings(复制命名空间映射) 页面上的 Close(关闭) ,返回到 Namespaces(命名空间) 页面,在该页面上列出了 USER2 命名空间。 您现在已经改变了容器中的实例。 接下来,停止该容器并将其作为名为 iris2 的新映像(image)提交,然后列出可用的映像。 $ docker stop iris $ docker commit iris acme/iris2:test sha256:7b4adb9f7abf1490a39086665ccd3d255c05163c25cb9a3de8e9421f6ca16b40 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE acme/iris2 test 421f6ca16b40 8 seconds ago 1.40GB intersystems/iris 2020.3.0.221.0 15627fb5cb76 1 hour ago 1.39GB centos 7.3.1611 262f7381844c 2 weeks ago 192MB hello-world latest 05a3bd381fc2 7 months ag 1.84kB 最后,删除从原始 iris 映像创建的容器。 $ docker rm iris iris 7.运行和调查第二个基于 InterSystems IRIS 的容器 为了总结这一体验,您将使用 docker run 命令从您刚刚提交的基于 InterSystems-IRIS 的映像中创建并启动一个容器,包括用于持久化特定于实例的数据的持久化 %SYS 功能(durable %SYS feature)。持久化 %SYS (durable %SYS)是保存特定于实例的数据以及您对它所做的任何更改的一种更有用的方法。因为这些数据被保存在容器之外,它可以成为新的 InterSystems IRIS 容器的数据,允许您通过运行后面的映像(image)的容器来升级 IRIS 实例,同时保留以前的容器的数据;当内部容器更改提交到新映像时,这是不可能的。有关持久化 %SYS (durable %SYS)的详细信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Durable %SYS for Persistent Instance Data(持久化实例数据的持久化 %SYS )。当您启动新容器后,将执行以下操作: 确认在作为一个新映像(image)提交的容器中创建的命名空间(请参见 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交))存在于新容器中的 InterSystems IRIS 实例中。 在容器中更改 InterSystems IRIS 实例的设置,并查看它反映在容器外持久化 %SYS (durable %SYS)数据中。 确认您添加的演示文件在容器内存在。 要做到这一点,请遵循以下步骤: 为这个容器确定一个外部存储位置。您可以使用在 Add the License Key to the External Storage Location(添加许可证密钥到外部存储位置)中为前一个容器选择的许可证密钥,也可以选择一个新的。许可证密钥应该仍然在以前的位置。(如果您使用一个新的位置,请确保许可证密钥已经到位)。 创建一个 docker run 命令,类似您在 Run a Container from the InterSystems IRIS Image(从 InterSystems IRIS 映像运行容器)中执行的命令, 基于那里的指令,但有两个更改。 添加选项 --env ISC_DATA_DIRECTORY=pathname 标识持久化 %SYS(durable %SYS) 目录,即写入 InterSystems IRIS 实例的持久化数据(persistent data)的位置。持久化 %SYS目录(durable %SYS directory)必须在一个挂载的 volume 上(请参见--volume 选项和 Add the License Key to the External Storage Location(添加许可证密钥到外部存储位置))。 注意: InterSystems 建议指定挂载 volume 的子目录为持久化 %SYS 的位置。下面的 docker ps 示例显示了这一点。 使用映像:标签(image:tag) 指定新映像 之前,您从 intersystems/iris:2021.1.0.205.0 (即 InterSystems 提供的映像)创建了容器;这次,您使用的是 acme/iris2:test,这是您通过提交更改过的 iris 容器创建的。 调用容器 iris2。当 docker run 命令完成后,使用 docker ps 命令来列出容器并查看其状态。例如: $ docker run --name iris2 --detach --publish 52773:52773--volume /nethome/pmartinez/iris_external:/external --env ISC_DATA_DIRECTORY=/external/durable acme/iris2:test --key /external/iris.key bdfe214ef76a34290a8308cddce92162aae14df1ba1bc244e692af3c8d911a3e $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS af3c8d911a3e acme/iris2:test "/iris-main --key ..." 5 seconds ago Up 3 seconds PORTS NAMES 0.0.0.0:52773->52773/tcp iris2 注意: InterSystems IRIS 社区版(Community Edition)映像(请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像))不需要--key 选项,该映像附带一个免费的内置许可证。 Docker Compose 是一个用于定义和运行多容器应用程序的工具,为 Docker 命令行交互提供了替代方案。要使用 Compose,您需要创建 docker-compose.yml ,其中包含您想要创建、启动和管理的容器的规范,然后使用 docker-compose 命令。更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Running an InterSystems IRIS Container:Docker Compose Example(运行 InterSystems IRIS 容器:Docker Compose 示例),和 Docker 文档中的 Overview of Docker Compose(Docker Compose 概述)。 确认从已更改的 InterSystems 容器提交的更改 在 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交)中,您在从 InterSystems 提供的映像 intersystems/iris:2021.1.0.205.0 创建的容器中为 InterSystems IRIS 实例添加了一个命名空间,然后将该容器作为一个新映像 acme/iris2:test 提交。因此,您添加的命名空间应该存在于运行在 iris2 容器内的 InterSystems IRIS 实例中,该容器是从 acme/iris2:test 创建的。 要确认这一点,请执行以下操作: 打开管理门户(Management Portal)并登录,如 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交)中所述。 从主页上,选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Namespaces(命名空间),来显示命名空间(Namespaces)页面;在 iris 容器中创建的 USER2 命名空间被列出。 探索和更改持久化 %SYS 目录 要探索 InterSystems IRIS 容器的持久化 %SYS 功能,请执行以下操作: 要查看 InterSystems IRIS 在容器外写入的特定于实例的数据,因为您在 docker run 命令中包含了持久化 %SYS 环境变量,显示您在该变量中指定的目录的内容,该目录在您使用--volume 选项指定的存储位置,作为要挂载的外部 volume。例如,如果该目录被指定为 /nethome/pmartinez/iris_external/durable,如示例 docker run 中所示,您会做如下操作 $ cd /nethome/pmartinez/iris_external $ ls durable iris.key $ ls durable csp dist httpd iris.cpf iris.cpf_20180417 _LastGood_.cpf mgr $ ls durable/mgr alerts.log irisaudit iris.ids irislocaldata iristemp IRIS.WIJ journal.log startup.last SystemMonitor.log user ilock IRIS.DAT iris.lck iris.shid iris.use journal messages.log stream Temp 返回容器中 InterSystems IRIS 实例的管理门户(Management Portal),选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Journal Settings(日志设置) 以显示日志设置(Journal Settings)页面。 Secondary journal directory(二级日志目录)设置从 /external/durable/mgr/journal/ 更改为 /external/durable/mgr/journal2/,并点击 Save(保存)。 返回到命令行,再次列出持久化 %SYS 目录的 mgr 子目录: $ ls /nethome/pmartinez/iris_external/durable/mgr alerts.log irisaudit iris.ids iris.lck iris.shid iris.use journal journal.log messages.log stream Temp ilock IRIS.DAT iris.key irislocaldata iristemp IRIS.WIJ journal2 licmanager.port startup.last SystemMonitor.log user 由于您对容器内的 InterSystems IRIS 实例进行了更改,所以 journal2 子目录被添加到容器外 。 这个示例显示了持久化 %SYS (durable %SYS)如何使您通过从新映像(image)创建容器来升级容器化的 InterSystems IRIS 实例。您对实例所做的所有持久化更改都存储在容器外的持久化 %SYS 目录(durable %SYS directory);如果您使用所需的选项从任何 InterSystems IRIS 映像(image)创建并启动一个新容器 — 即--volume 选项为持久化 %SYS (durable %SYS)挂载外部存储位置,以及--env ISC_DATA_DIRECTORY 选项指定该挂载 volume 上持久化 %SYS(durable %SYS) 位置,该位置必须存在,并且包含一个 /mgr 子目录 — 这些更改由实例继承,因为它使用与前一个容器中的实例相同的数据。 4.了解有关容器中的 InterSystems IRIS 的更多信息 此时,您已经准备好继续探索容器和 InterSystems IRIS 必须提供的东西。使用下面的文档和参考资料来深入了解容器和 InterSystems IRIS。 Docker Containers and InterSystems IRIS(《Docker 容器和 InterSystems IRIS》) (视频) Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》) 来自 InterSystems 开发者社区(Developer Community)的文章: What is a Container?(《什么是容器?》) What is a Container Image?(《什么是容器映像?》) Using InterSystems IRIS Containers with Docker for Windows(《使用 InterSystems IRIS 容器与 Docker for Windows》) Docker Documentation(《Docker 文档》) InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)——使用 InterSystems 云管理器(InterSystems Cloud Manager,ICM)可以轻松直观地配置基础设施,并以各种方式在上面部署容器。ICM 为 InterSystems IRIS 带来了基础设施即代码(Infrastructure as Code,IaC)和容器化部署的好处,而不需要在新技术、培训、配置和管理方面进行重大投资。本指南包含有关 ICM 和使用 InterSystems IRIS 与 Docker 容器的文档。 First Look:InterSystems Cloud Manager(《技术概要:InterSystems 云管理器》)
公告
Michael Lei · 十月 26, 2021

InterSystems IRIS和InterSystems IRIS for Health的完整套装版本供开发人员使用!

InterSystems很高兴地宣布一个全新的 开发者下载网站 提供InterSystems IRIS社区版和InterSystems IRIS for Health社区版的完整配套版本。 这些都是免费提供给应用开发者使用的。 你可以选择直接从 InterSystems开发者社区 直接 下载 InterSystems IRIS. 这些实例包括一个免费的内置13个月的许可证。 它们限制在10GB的用户数据,将在8个核心的机器上运行,支持5个并发连接,并支持应用开发。可用的平台。RedHat, Ubuntu, SUSE, Windows和macOS InterSystems IRIS 和 InterSystems IRIS for Health医疗版也可以从Docker Hub获得容器版. 请在这里查看如何开始,访问我们网站上的InterSystems IRIS 数据平台或InterSystems IRIS for Health 医疗版,了解更多关于我们的产品,并访问 开发者资源页面深入了解开发。 如果您之前注册了InterSystems登录账户(如开发者社区或WRC),您可以使用这些账户来访问开发者下载网站 。
公告
Claire Zheng · 十月 23, 2021

2021全球峰会! Win. Win. Win with InterSystems Developer Ecosystem~

亲爱的开发者们, 是否准备参加InterSystems 2021全球峰会呢?不要错过InterSystems Developer Community、Open Exchange和Global Masters的专题会议! ⚡️ "Win. Win. Win with InterSystems Developer Ecosystem" VSummit21 session ⚡️ 🎁 注意:所有参会者都将获得额外奖励哦~ 分享嘉宾:🗣 @Anastasia.Dyubaylo, InterSystems开发者社区经理 🗣 @Lena.Evsikova, Product Owner of InterSystems Open Exchange🗣 @Olga.Zavrazhnova2637, Customer Advocacy Manager, InterSystems 了解如何更好地使用 InterSystems 开发者社区、Global Masters (游戏化中心)和Open Exchange(应用程序库)。 兴趣: 开发经验,InterSystems IRIS,用户社区 论坛从10月27日起即可观看!(中国用户需注册观看) 来吧! 加入我们的会议,享受InterSystems技术和我们为开发者提供的生态系统的完整体验!
文章
Claire Zheng · 十月 22, 2021

InterSystems 2021全球线上峰会邀您参会(内含福利)

10月26日-29日,InterSystems 2021全球线上峰会将聚焦于“Analytics”,为您提供全球先进经验和分享。 除了丰富的演讲外,针对使用InterSystems技术的开发者们,InterSystems的认证团队提供了最新福利,注册参加InterSystems2021全球线上峰会,可在2021年12月31日前免费参加以下几项认证考试(价值150美元,每人限选一项): InterSystems IRIS Core Solutions Developer Specialist 考核认证使用ObjectScript和其他InterSystems IRIS®技术构建应用程序的开发人员的核心技能。 HealthShare HealthConnect HL7 Interface Specialist 考核认证使用Health Connect构建和测试HL7®v2 新产品的开发人员的核心技能。 HealthShare Unified Care Record Technical Specialist 考核认证实施、扩展和管理HealthShare®统一健康档案(Unified Care Record)各个方面的技术专业人员的核心技能。 HealthShare Patient Index Technical Specialist (Beta) 考核认证实施、培训和支持HealthShare Patient Index各个方面的技术专业人员的核心技能。 如果您对该项目感兴趣,请在峰会结束后至11月12日(含)发邮件至wechat@intersystems.com进行咨询、申请,申请通过后,需要在12月31日前完成考试。 10月26日-27日,我们为中国用户专门开通了本地直播平台,欢迎点击免费注册参会。
文章
Claire Zheng · 十月 19, 2021

如何在InterSystems开发者社区学习?第二部分:标签(Tags)

Hi 亲爱的开发者们, 在这篇帖子中,我们将向您展示如何善用开发者社区的各类标签(Tags),让我们充分利用这个开发者社区的选项吧! 一个标签(Tag)就是一个描述帖子主题的单词或短语,是一种将开发者社区成员和专家与文章联系起来的方法,通过合理地运用标签(Tag),他们将能够讨论/给出正确的答案,将文章分类为具体的、定义明确的类别。 标签(Tag)也可以用来帮助你识别你感兴趣或相关的文章。 在开发者社区顶部的菜单中,你可以看到 标签(Tag)完整列表 标签(Tag)的类型和开发者社区的标签树(Tag Tree) 在开发者社区有两种标签: 标签组(Groups)– 所谓的主标签,用于标识广泛的主题,包括所有InterSystems技术。 标签(Tags)–用于更专门化主题的常规标签。 每个帖子必须至少有一个这样的组(Group)。你知道所有的组(Group)吗? 针对InterSystems technology的标签组 (9): 针对 Visual Studio Code的标签组: InterSystems开发者社区的官方声明标签组“official announcements” : 来自Worldwide Response Center (WRC)的警告和警报标签组: Open Exchange的一个标签组(InterSystems软件解决方案和框架的InterSystems库),另一个标签组是Global Masters(InterSystems游戏化平台),还有一个另一个标签组是Partner Directory (合作伙伴目录,客户和合作伙伴的InterSystems平台): 标签组Global Summit(全球峰会),这是InterSystems的年度盛会: 标签组Online Learning (在线学习)和Documentation(文档): 供用户进行评论、发表意见、提供建议的标签组 DC Feedback: 与InterSystems技术相关的工作标签组 job opportunity announcements (工作机会发布): 用以标记那些无法用前述标签归类的文章的标签组Others: 除了标签组(Group)之外,开发者社区成员还使用标签(Tags)来指定更多的帖子内容。 在 开发者社区标签树(Tag Tree),你会看到一些子标签(subtags),对标签的内容进行分类。 例如,在"语言(Languages)"标签下有如下子标签:"C++", "Python", "JavaScript", "MultiValue Basic", "ObjectScript", "Java" and ".NET". 需要注意的是,为帖子加标签(Tags)并非强制性的,但是在发帖前你必须为帖子选择至少一个"标签组(Groups)”: 标签(Tags)归类: 你可以通过 开发者社区标签树(Tag Tree)以三种不同方式为标签归类: 1. 按热门程度: 标签组(Groups)和标签(Tags)根据它们在帖子中被使用的次数排列,这个数字会出现在每个标签(Tag)旁边的括号内。 例如,标签“Open Exchange” 出现在了368篇帖子中: 2. 按名称: 标签组(Groups)和标签(Tags)按字母顺序排列。 3. 按新增: 在这种模式下,新增标签组(Groups)和标签(Tags)会出现在最前面。 标签(Tag)页:按标签关注、排序、筛选文章 每个标签(Tag)都有自己的URL/网页,在那里你可以看到所有使用该标签的帖子。 例如, "XML" 标签(Tag)的标签页面是:https://cn.community.intersystems.com/tags/xml, 在这个页面展示了所有使用这一标签的文章: 在标签页面上,所有的帖子都可以通过不同的标准进行再次排列:按更新时间、按日期、按点赞、按查看数、按回复。 它们也可以按发布类型分类:公告、文章、问题、讨论、视频或工作。你需要到左上角的菜单,选择你要找的文章类型。 快来关注你感兴趣的标签(Tags)吧! 如果你对某个主题感兴趣,你可以在开发者社区标签树(Tag Tree)中寻找它的标签,选择它,然后点击它旁边的“关注”按钮。当你关注了某一标签(Tags)时,你会收到所有使用该标签(Tags)的帖子的邮件。 我们推荐您可以关注以下标签: Best practices(最佳实践) | Tips and tricks(提示和技巧) | Beginner(初学者) | Tutorial(教程). 那么,现在就来看看开发者社区标签树(Tag Tree)吧——一大波儿有趣的主题(标签)和各种有用的内容正在等着你! 阅读所有与你感兴趣的主题相关的文章; 关注标签走,这样你就不会错过任何关于你最喜欢的话题的帖子了。 如果你有任何关于标签(Tags)的问题,或者你想@任何人,请在下面留下你的评论/建议!
文章
Nicky Zhu · 十月 18, 2021

IRIS 2021 技术文档 First Look 27--基于角色的访问控制

目录 技术概要: 基于角色的访问控制 1 基于角色的访问控制:为什么它很重要? 1 基于角色的访问控制:如何在 InterSystems IRIS 中工作 1 简要概念概述 1 示例用例 2 基于角色的访问控制:探索它 3 用前须知 3 发现管理门户(Management Portal)页面访问所需的资源 3 创建和分配您自己的管理者角色 4 创建用户并分配新角色 5 尝试管理门户(Management Portal)中的角色 6 了解有关基于角色的访问控制的更多信息 7 技术概要:基于角色的访问控制 本文档向您介绍基于角色的访问控制,解释它在 InterSystems IRIS®数据平台中的工作原理,并帮助您亲自探索。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 基于角色的访问控制:为什么它很重要? 当您首次开始使用一个新的数据库平台时,有件事情可能很快就会变得清晰起来:您可能不希望企业中的所有用户都查看和更改系统上的所有内容。 InterSystems IRIS 和所有的数据库平台一样,允许您精细指定 InterSystems IRIS 的每个用户可以执行的操作。我们用来控制用户授权(authorization)执行操作的机制被称为基于角色的访问控制(role-based access control)。 如果您已经熟悉了基于角色的访问控制,InterSystems IRIS 方案很可能与您以前使用过的一些方案相似。您会在下一节找到有关我们如何处理它的更多细节。 如果您是基于角色的访问控制的新手,这意味着比旧的访问控制方法节省时间,因为旧的访问控制方法没有提供执行系统操作的权限分组。 如果没有基于角色的访问控制,为每个用户逐个分配使用 InterSystems IRIS 的各个方面的权限可能需要数小时甚至数天。然后,如果有新员工需要访问,您将不得不重复这个过程。 基于角色的访问控制允许您在初始配置 InterSystems IRIS 时将权限分组到角色中。然后,您可以为每个系统用户分配一个或多个现成的角色。您还可以使用或修改一组预定义的角色<span id="2_Role-Based_Access_Control:_How_It_Work" class="anchor"></span>。 此外,通过基于角色的访问控制,如果用户需要使用一组新的权限,则可以将该组权限分组为一个角色,并将该角色分配给用户。而且您可以随时改变角色内的权限列表。 基于角色的访问控制: 如何在 InterSystems IRIS 中工作 InterSystems IRIS 为基于角色的访问控制提供了一个完整的解决方案,我们将在本节中对此进行描述。InterSystems IRIS 支持的每一种认证机制,包括 LDAP、Kerberos 和 OS-based,都可以使用本地 InterSystems 基于角色的访问控制。如果您愿意,您可以使用 LDAP 而不是 InterSystems IRIS 进行角色分配。 简要概念概述 把 InterSystems IRIS 中的信息和功能视为您要保护的资产 ,就像您为属于您的资产投保一样。 基于角色的访问控制:如何在 InterSystems IRIS 内部工作 在 InterSystems IRIS 中被视为资产的项目包括: 数据库,将数据和代码作为对象存储。 服务,控制用户连接到 InterSystems IRIS 的能力。 某些管理权限。 InterSystems IRIS 应用程序,包括管理门户(Management Portal)中的各个页面,它是 InterSystems IRIS 的系统管理用户界面。 在 InterSystems IRIS 中,每项资产(asset)都由一个资源**(resource)来表示,一个资源(resource)可以表示多个资产(asset)。 资源(resource)充当它所代表的资产(asset)的看门人:根据资源类型,它与 "读取"、"写入"(包括读取),和在某些情况下的 "使用"(执行)权限(permission) 配对。例如,数据库只存在两种类型的权限:读取,允许查看数据和执行例程;写入,允许修改数据。 资源与权限的配对被称为权限(privilege),权限按角色(role)分组。 最后,角色(role)被分配给 InterSystems IRIS 中的用户(user) 。每个用户(user)在首次使用 InterSystems IRIS 进行认证时,都会有一个或多个角色(role)分配给他们。可以在会话期间向用户添加或删除角色(role)。 基于角色(role)的访问控制的具体授权方式取决于您所选择的认证机制。在线文档中完全涵盖了授权的这方面内容。 提示:对于内部测试和暂存系统,您可能不希望设置基于密码的认证或基于角色(role)的不同级别的访问控制。如果您使用 "最低(minimal)" 安全性来安装您的实例,这个选项是可用的,默认情况下,它给拥有实例的管理门户(Management Portal) URL 的任何人提供完全管理权限。 示例用例 如上所述,管理门户(Management Portal)中的各个页面是 InterSystems IRIS 中您可以保护的资产(asset)。管理门户( Management Portal)允许用户(user)查看和执行 InterSystems IRIS 基本方面的操作,如 globals、命名空间,甚至资源(resource)和角色(role)本身。 下面的屏幕截图显示了当实例的管理员使用安装时创建的 _SYSTEM 帐户登录时,管理门户(Management Portal)的外观和行为。 _SYSTEM 用户可以访问 System Administration(系统管理) > Security(安全)> Users(用户) ,让他们可以查看和修改任何用户(user)及其角色(role)。 您可能想限制某些管理门户(Management Portal)用户的角色(role)分配,使他们不能查看或修改用户(user)帐户或任何其他对安全至关重要的信息。在下一节,我们将告诉您如何做到这一点。 基于角色的访问控制: 探索它 下面的示例向您展示了如何设置两种类型的"管理者"角色,以便在管理门户(Management Portal)中使用。第一个角色将能够访问允许修改用户和角色定义等安全相关项的页面。第二个角色将没有这个访问权限。 然后您会看到拥有这些角色的用户如何与管理门户(Management Portal)交互。 重要提示: 为了让您体验 InterSystems IRIS,而又不陷入细节的困境,我们保持了简单的探索。例如,我们让您尽可能多地使用默认设置。 但是,当您把 InterSystems IRIS 引入您的生产系统时,您需要做很多不同的事情,特别是(但不限于)安全方面。 所以请确保不要把这种对 InterSystems IRIS 的探索与真实的情况相混淆!本文档末尾提供的参考资料将使您对在生产中使用 InterSystems IRIS 的情况有一个很好的了解。 用前须知 要使用该程序,您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。使用同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 .Net IDE 中的信息将 Visual Studio 连接到您的 InterSystems IRIS 实例。 发现管理门户(Management Portal)页面访问所需的资源 对管理门户(Management Portal)中的每个页面的访问都受到至少一种资源的保护。您可以通过以下方式发现所需的资源: 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中URL described for your instance(为您的实例描述的 URL),在浏览器中打开您的实例的管理门户(Management Portal)。 通过点击相应菜单项中的每一个单词,导航至 System Administration(系统管理) > Security(安全)。 基于角色的访问控制:探索它 提示: 在管理门户(Management Portal)中,带有子页面的菜单项在其名称旁边包含 >>。页面没有这样的标记。 在 Users(用户) 菜单项中,点击"用户(Users)"一词右侧的任何位置。这个操作显示查看 Users(用户)页面所需的资源,即 %Admin_Secure。(Security(安全) 和 Encryption(加密) 子菜单中的所有页面都需要 %Admin_Secure 资源上的使用权限("U")。) 导航至 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置)。 点击"内存和启动(Memory and Startup)"右侧的任何位置。您会看到,查看该页面所需的资源是 %Admin_Manage。 创建和分配您自己的管理者角色 对于管理门户(Management Portal)的 System Administration(系统管理)菜单内的页面,您需要具有 %Admin_Secure 和 %Admin_Manage 资源权限的角色。 鉴于这种结构,您可能希望创建两个反映管理级别的角色,一个是可以访问除安全相关页面以外的所有页面,另一个是可以执行所有操作,包括安全相关的操作。您可以使用预定义的 %Managerrole 作为模板。 使用 _SYSTEM 帐户登录管理门户(Management Portal)。 导航至 System Administration(系统管理) > Security(安全) > Roles(角色) ,并点击 Go。您将看到安装了 InterSystems IRIS 的角色列表,包括 %Manager 角色。 点击 %Manager 链接。 General(常规) 标签显示具有此角色的用户可用的权限(与权限配对的资源)。 在权限中,您会看到 %Admin_Secure 和 %Admin_Manage 上的使用权限。 您也会看到许多其他的权限。这是因为您需要访问许多不同的资源,才能够查看和修改 InterSystems IRIS 设置。既然我们知道只有一种关键资源 %Admin_Secure,在 System Administration(系统管理)的安全相关页面的访问方面,对该资源的访问将是我们两个自定义角色之间的唯一区别。 点击 Cancel(取消) (在 Edit %Manager 下面),返回到主 Roles(角色)页面。 创建 "标准管理者"角色 在 Roles(角色)页面上,点击 Create New Role(创建新角色)。将出现一个角色定义页面。 基于角色的访问控制:探索它 在 Name(名称) 字段中,输入"Standard_Mgr"。 在 Copy from(复制自) 下拉菜单中,选择 %Manager。这将复制所有信息,包括权限,从预定义 %Manager 角色到新角色。 将描述更改为您所选择的描述,例如:"Role for System Administration without security access(不具有安全访问权限的系统管理角色)"。 点击 Save(保存)。将出现一条 Role saved(保存角色) 信息,您将在 General(常规)标签中看到新角色的权限列表。 在 %Admin_Secure 行中,点击 Delete(删除)。这就从角色中删除了权限。 再次点击 Save(保存) 来保存更改。 创建"安全管理员"角色 在 Roles(角色)页面上,点击 Create New Role(创建新角色)。将出现一个角色定义页面。 在 Name(名称) 字段中,输入"Security_Mgr"。 在 Copy from(复制自)下拉菜单中,选择 %Manager。这将复制所有信息,包括权限,从预定义 %Manager 角色到新角色。 将描述更改为您所选择的描述,例如:"Role for System Administration with securityaccess(具有安全访问权限的系统管理角色)" 点击 Save(保存)。将出现一条 Role saved 信息,您将在 General(常规)标签中看到新角色的权限列表。 创建用户并分配新角色 要查看角色的运行情况,需要创建两个用户,每个用户对应一个新角色。 使用 _SYSTEM 帐户登录管理门户(Management Portal)。 导航至 System Administration(系统管理) > Security(安全) > Users(用户),并点击 Go。您将看到安装了 InterSystems IRIS 的用户定义列表。 创建"标准管理员"用户 在主 Users(用户) 页面上,点击 Create New User(创建新用户)。将出现一个用户定义页面。 在 Name(名称) 字段中,输入"Std_Mgr"。(用户的名称不能与角色的名称一致)。 在 Password(密码) 和 Password (confirm)(确认密码) 字段中,输入您选择的密码。 点击 Save(保存)。将出现一条 User saved 信息。 点击 Roles(角色)标签。滚动左侧的 Available 列表,并高亮显示 Standard_Mgr(标准管理员)。 点击右箭头 ,将该角色添加到 Selected(已选)列表中。然后点击"Assign(分配)"。 7. 点击 Cancel(取消) 以返回到主 Users(用户)页面。 创建"安全管理员"用户 在主 Users(用户) 页面上,点击 Create New User(创建新用户)。将出现一个用户定义页面。 在 Name(名称) 字段中,输入"Sec_Mgr"。 在 Password(密码) 和 Password (confirm)(确认密码) 字段中,输入您选择的密码。 基于角色的访问控制:探索它 点击 Save(保存)。将出现一条 User saved 信息。 点击 Roles(角色)标签。滚动左侧的 Available 列表,并高亮显示 Security_Mgr(安全管理员)。 点击右箭头,将该角色添加到 Selected(已选)列表中。然后点击 Assign(分配)。 点击 Cancel(取消) 以返回到主 Users(用户)页面。 尝试管理门户(Management Portal)中的角色 以 Std_Mgr 用户(标准管理员用户)登录管理门户(Management Portal)。您将看到,与安全有关的菜单选项是灰色的,正如预期的那样。Interoperability(互操作性)菜单选项也是灰色的,因为从其中复制两个自定义角色的预定义 %Manager 没有访问这些页面所需的权限。 退出,然后以 Sec_Mgr 用户(安全管理员用户)重新登录。 正如您所看到的,这个用户具有对 System Administration(系统管理) > Security(安全)和 System Administration(系统管理) > Encryption(加密) 子菜单中的页面的完全访问权限。 了解有关基于角色的访问控制的更多信息 要了解有关基于角色的访问控制和 InterSystems IRIS 安全模型的更多信息,请参见: About InterSystems Security(《有关 InterSystems 安全》)中的 "Authorization:Controlling User Access(授权:控制用户访问)"一节 InterSystems IRIS Programming Orientation Guide(《InterSystems IRIS 编程指南》)中的 "InterSystems IRIS Security(InterSystems IRIS 安全)"和 "Namespaces and Databases(命名空间和数据库)"部分 --- 为应用程序开发人员提供有关基于角色的访问控制的信息。 Security Tutorial(《安全教程 》)中的 "Authorization(授权)"部分 --- 创建用户、角色和权限的逐步说明。
公告
Michael Lei · 十月 7, 2021

InterSystems 安全基础线上课程上线

InterSystems 安全基础线InterSystems Security Basics 通过本课程可以: 识别安全模式下的各个组件. 选择合适的认证方法. 创建用户和角色. 利用针对资源的许可来保护资产. 激活系统审计. https://learning.intersystems.com/course/view.php?id=1774 这个网址国内打不开么 应该可以的,learning 网站不需要翻墙 谢谢,已经打开了,当时应该是网络不太好吧。
文章
姚 鑫 · 九月 30, 2021

第三十一章 SQL命令 DROP DATABASE

# 第三十一章 SQL命令 DROP DATABASE 删除数据库(命名空间)。 # 大纲 ```sql DROP DATABASE dbname [RETAIN_FILES] ``` ## 参数 - `dbname` - 要删除的数据库(命名空间)的名称。 - `RETAIN_FILES` - 可选-如果指定,则不会删除物理数据库文件(`IRIS.DAT`文件)。默认情况下,删除`.dat`文件以及命名空间和其他数据库实体。 # 描述 `DROP DATABASE`命令删除命名空间及其关联的数据库。 指定的`dbname`是包含相应数据库文件的命名空间和目录的名称。指定`dbname`作为标识符。命名空间名称不区分大小写。如果指定的`DBNAME`命名空间不存在, IRIS将发出`SQLCODE-340`错误。 `DROP DATABASE`命令是一个特权操作。 在使用`DROP DATABASE`之前,必须以`%Admin_Manage`资源的用户身份登录。 用户还必须拥有用于例程和全局数据库定义的资源的`READ`权限。 如果不这样做,将导致`SQLCODE -99`错误(权限冲突)。 使用`$SYSTEM.Security.Login()`方法为用户分配适当的权限: ```java DO $SYSTEM.Security.Login("_SYSTEM","SYS") &sql( ) ``` 必须具有`%Service_Login:Use`权限才能调用`$SYSTEM.Security.Login`方法。 不管权限如何,`DROP DATABASE`都不能用于删除系统命名空间。尝试这样做会导致`SQLCODE-342`错误。 `DROP DATABASE`不能用于删除当前正在使用或连接到的命名空间。尝试这样做会导致`SQLCODE-344`错误。 还可以使用管理门户删除命名空间。依次选择System Administration、Configuration、System Configuration、Namespaces以列出现有的`Namespace`。单击要删除的命名空间的删除按钮。 ## RETAIN_FILES 如果指定此选项,则保留物理文件结构;删除数据库及其关联的命名空间。执行此操作后,后续尝试使用`DBNAME`将导致以下结果: - `DROP DATABASE`不带`RETAIN_FILES`无法删除此物理文件结构。相反,它会导致`SQLCODE-340`错误(未找到数据库)。 - `DROP DATABASE WITH RETAIN_FILES`还会导致`SQLCODE-340`错误(找不到数据库)。 - `CREATE DATABASE`无法创建同名的新数据库。相反,它会导致`SQLCODE-341`错误(无法为数据库创建数据库文件)。 - 尝试使用此命名空间会导致``错误。 ## 服务器初始化和断开代码 服务器初始化代码和服务器断开代码可以通过`$SYSTEM.SQL.Util.SetOption("ServerInitCode",value)`和`$SYSTEM.SQL.Util.SetOption("ServerDisconnectCode",value)`方法分配给命名空间。 可以使用相应的`$SYSTEM.SQL.Util.GetOption()`方法选项来确定当前值。 使用`DROP DATABASE`或其他接口删除命名空间,将删除这些`Server Init Code`和`Server Disconnect Code`值。 因此,删除并重新创建名称空间需要重新指定这些值。 # 示例 ```sql CREATE DATABASE DocTestDB ON DIRECTORY 'c:\InterSystems\IRIS142\mgr\DocTestDB' ``` ```sql DROP DATABASE DocTestDB RETAIN_FILES ```
公告
Michael Lei · 九月 29, 2021

新一轮InterSystems开发者竞赛开始啦: 互操作性大赛

亲爱的社区开发者们,大家好! 欢迎积极参与新一轮InterSystems系联开发者竞赛! 🏆 InterSystems 互操作性大赛 🏆 时间: 2021年10月4日--24日 总奖金池高达 9,450美金! 奖项设置 1. 专家提名奖(Experts Nomination) - 获奖者由我们特别挑选的专家团选出: 🥇 第1名 - $4,000 🥈 第2名 - $2,000 🥉 第3名 - $1,000 🌟 新设奖项: 第4到第10名 - $100 2. 社区提名奖(Community Nomination) -获得总投票数最多的应用: 🥇 第1名 - $1,000 🥈 第2名 - $500 🥉 第3名 - $250 如果同时多位参赛者获得同样的票数,均被视为优胜者,将平分奖金 谁可以参加? 任何开发者社区的成员均可参加,InterSystems内部员工除外(InterSystems contractor员工可以参加)。还没有账号?现在来建一个! 👥 开发者可以组团 创建一个协作应用程序,组团限定人数为2-5人。 请注意,要在您的README文件中标注您的团队成员——社区用户profile 参赛时间安排 🛠 10月 4日-17日: 应用开发、提交阶段 ✅ 10月 18日 - 24日: 投票阶段 注意:在整个参赛期间(开发与投票期间,即10月4日-10月24日),开发者可持续编辑、完善其应用程序 主题 💡 InterSystems IRIS 与 IRIS 医疗版互操作性解决方案 💡 基于InterSystems IRIS 或 InterSystems IRIS 医疗版开发一个互操作性解决方案或者能够帮助开发或维护互操作性的方案; 参赛须知: 有效应用程序:100%全新的Open Exchange Apps或已有的应用程序(但有显著提升)。所有参赛者/团队提交的应用程序只有经过我们团队的审核之后才会被批准参赛。 该应用应该在 IRIS Community Edition or IRIS for Health Community Edition or IRIS Advanced Analytics Community Edition 上工作。 该应用需开源并在GitHub上发布。 该应用的README文件应为英文,包含安装步骤,并包含视频demo或/和应用程序如何运行的描述。 技术资源 1. IRIS初学者: Build a Server-Side Application with InterSystems IRIS Learning Path for beginners 2. 应用样例: Ensemble/互操作性构成 IRIS-互操作性-模版 ETL-互操作性-适配器 InterSystems IRIS医疗版互操作性Demo ENSDEMO HL7 和 SMS 互操作性 Demo 医疗行业 HL7 XML RabbitMQ 适配器 基于Kafka的产品扩展 demo 3. 在线课程和视频: 企业中的互操作性 互操作性快速入门指南 互操作性资源 - 2019 智慧的互操作性 医疗互操作性概览 4. 如何将您的APP提交给大赛 如何在InterSystems Open Exchange上发布应用程序 如何把参赛APP提交给大赛 参赛评比 投票规则即将发布,敬请期待! 各就位,预备,跑! 期待您的精彩提交!加入我们的编程马拉松,赢取大奖 ❗️ 点击此处,查看 官方竞赛条款解读❗️
文章
Jingwei Wang · 九月 28, 2021

IRIS 2021 技术文档 First Look 16 Java 网关(Gateway)和InterSystems 产品

本文档介绍了如何在 InterSystems IRIS®数据平台中使用 Java 网关(Gateway)与 Java 组件进行互操作。在本文中,您将首先创建一个示例 JAR 文件。然后,您将在 InterSystems IRIS 管理门户(Management Portal)中创建并启动 Java 网关(Gateway)。您将以编程方式导入创建的示例 JAR 文件。最后,您将在 ObjectScript 中创建并操作一些代理类(proxy class)和对象(object)。 为了让您体验 Java 网关(Gateway ),而又不陷入细节困境,我们保持了简单的探索。这些活动被设计成只使用默认设置和功能,这样您就可以熟悉功能的基本原理,而不必处理那些离题或过于复杂的细节。当您把 Java 网关(Gateway)引入您的生产系统时,您可能需要做一些不同的事情。请确保不要把这种对 Java 网关(Gateway )的探索与真实的情况相混淆!本文档末尾提供的参考资料将使您对在生产中使用 Java 网关(Gateway)的情况有一个很好的了解。 要浏览所有的技术概要(First Look),包括下面描述的可以在免费的社区版(Community Edition)实例上执行的那些,请参见 InterSystems 技术概要。 为什么 Java 网关(Gateway)很重要 Java 网关(Gateway)为 InterSystems IRIS 与 Java 组件进行互操作提供了一种简单的方法。在使用 Java 网关(Gateway)导入 JAR 文件后,您可以实例化一个外部 Java 对象,并将其作为 InterSystems IRIS 中的本机对象进行操作。您可以从 InterSystems IRIS 和 ObjectScript 内部访问 Java 类和方法! 在内部,Java 网关(Gateway)为每个 Java 类生成一对一的 ObjectScript 代理。通常,使用 Java 网关(Gateway)的最佳方法是构建一个小型 Java 封装类(wrapper class),它只公开您想要的功能,然后为这个封装创建一个代理。 探索 Java 网关(Gateway) 我们开发了一个简短的演示,向您展示如何使用 Java 网关(Gateway)和 InterSystems IRIS。想试试InterSystems IRIS Java 开发和互操作性功能的在线视频演示吗?请查看 Java QuickStart(Java 快速入门)! 用前须知 要使用该程序,您需要在一个系统上工作,应安装 JDK 1.8 版本和您选择的 Java IDE,并连接一个正在运行的 InterSystems IRIS 实例。您对 InterSystems IRIS 的选择包括多种已授权的和免费的评估实例;实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见InterSystems IRIS 基础:连接一个 IDE中的部署 InterSystems IRIS。使用同一文档中的InterSystems IRIS 连接信息和 Java IDE中的信息,将 IDE 连接到您的 InterSystems IRIS 实例。 创建 JAR 文件 使用您选择的 IDE 在 Java 中创建 Person 类。使用以下示例代码: public class Person { public int age; public String name; //constructor public Person (int startAge, String Name) { age = startAge; name = Name; } public void setAge(int newAge) { age = newAge; } public String getName() { return name; } public int getAge() { return age; } public static void main(String []args) { Person myPerson = new Person (5, "Tom"); System.out.println(myPerson.getName()); System.out.println(myPerson.getAge()); }} 编译 Person 类。然后,打开命令提示符(Command Prompt)窗口,并导航到包含 Person.class 文件的目录。使用下面的命令来生成 Person.jar 文件: jar cf Person.jar Person.class 注意文件的位置。 启动 Java 网关(Gateway) 要启动 Java 网关(Gateway),请按照以下步骤操作: 使用InterSystems IRIS 基础:连接一个 IDE中为您的实例描述的 URL,在浏览器中打开您的实例的管理门户(Management Portal)。 导航到 Object Gateways(对象网关)页面。(System Administration(系统管理) > Configuration(配置) > Connectivity(连接) > External Language Servers 选择 Create New External Language Servers 下拉菜单选择 Java 。 服务器名称输入 JavaGatewayTest,端口输入 55555。 点击 Save(保存)。 在新的 Java 网关(Gateway)所在行中,点击 Start(开始)。 生成代理类(Proxy Classes) 在 USER 命名空间(或您在已安装的实例)中创建一个名为 CreateProxyClasses.cls 的新 ObjectScript 类,包名为 JavaGatewayTest。粘贴以下代码,用您的 InterSystems IRIS 实例的连接信息 (如InterSystems IRIS 基础:连接一个 IDE中所述)替换 gwyConn.&Connect 的参数。您可以指定所示的 USER 命名空间,也可以选择实例上创建的另一个命名空间。用双引号括起来的 Person.jar 文件的完整文件路径替换 YOUR FILEPATH HERE。 Class JavaGatewayTest.CreateProxyClasses Extends %Persistent { ClassMethod run() { // get a connection to the Java Gateway set gwyConn = ##class(%Net.Remote.Gateway).%New() set status = gwyConn.%Connect("127.0.0.1", 55555, "USER") if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // add the jar to the classpath set classpath = ##class(%ListOfDataTypes).%New() do classpath.Insert("YOUR FILEPATH HERE") set status = gwyConn.%AddToCurrentClassPath(classpath) if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // create the proxy ObjectScript classes that correspond to the Java classes in the jar file set status = gwyConn.%Import("Person",,,,1) if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit } // close the connection to the Java gateway set status = gwyConn.%Disconnect() if $$$ISERR(status) { write !,"error: "_$system.OBJ.DisplayError(status) quit }}} 编译并构建该类。 打开 InterSystems 终端(Terminal),并导航到您指定的命名空间。使用以下命令执行 run() 方法: do ##class(JavaGatewayTest.ManipulateObjects).run() 您应该可以看到以下输出: Name: Tom Age: 5 setting age to 100 Age: 100 现在您已经成功地完成了练习,停止您创建的 Java 网关(Gateway)。返回到管理门户(Management Portal)中的 External Language Servers页面,找到您的 JavaGatewayTest 网关,并选择 Stop(停止)。 了解有关 Java 网关(Gateway)的更多信息 要了解有关 Java 网关(Gateway)和 InterSystems IRIS 的更多信息,请参见: 使用 Java 网关(Gateway) 有个疑问,生成代理类(Proxy Classes)该步骤中是不是应该体现为JavaGateway而不是Net.Remote.Gateway。 %Net.Remote.Gateway 是 %Net.Remote.Java.JavaGateway的基类,是用来建立JavaGateway的连接使用的。
文章
Nicky Zhu · 九月 27, 2021

IRIS 2021 技术文档 First Look 17 Globals

html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; } .mac-os-11 { --title-bar-height: 28px; } html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; } body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; } iframe { margin: auto; } a.url { word-break: break-all; } a:active, a:hover { outline: 0px; } .in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); } #write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; } #write.first-line-indent p { text-indent: 2em; } #write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; } #write.first-line-indent li { margin-left: 2em; } .for-image #write { padding-left: 8px; padding-right: 8px; } body.typora-export { padding-left: 30px; padding-right: 30px; } .typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; } .typora-export .task-list-item input { pointer-events: none; } @media screen and (max-width: 500px) { body.typora-export { padding-left: 0px; padding-right: 0px; } #write { padding-left: 20px; padding-right: 20px; } .CodeMirror-sizer { margin-left: 0px !important; } .CodeMirror-gutters { display: none !important; } } #write li > figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max-width: 100%; vertical-align: middle; image-orientation: from-image; } button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; } input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; } *, ::after, ::before { box-sizing: border-box; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; } p { line-height: inherit; } h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; } p { orphans: 4; } h1 { font-size: 2rem; } h2 { font-size: 1.8rem; } h3 { font-size: 1.6rem; } h4 { font-size: 1.4rem; } h5 { font-size: 1.2rem; } h6 { font-size: 1rem; } .md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; } .hidden { display: none; } .md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; } a { cursor: pointer; } sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; } #write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; } figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; } figure > table { margin: 0px; } tr { break-inside: avoid; break-after: auto; } thead { display: table-header-group; } table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; } table.md-table td { min-width: 32px; } .CodeMirror-gutters { border-right-width: 0px; background-color: inherit; } .CodeMirror-linenumber { } .CodeMirror { text-align: left; } .CodeMirror-placeholder { opacity: 0.3; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-lines { padding: 0px; } div.hr:focus { cursor: none; } #write pre { white-space: pre-wrap; } #write.fences-no-line-wrapping pre { white-space: pre; } #write pre.ty-contain-cm { white-space: normal; } .CodeMirror-gutters { margin-right: 4px; } .md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; } .md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; } #write .md-fences.mock-cm { white-space: pre-wrap; } .md-fences.md-fences-with-lineno { padding-left: 0px; } #write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; } .md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; } .CodeMirror-line, twitterwidget { break-inside: avoid; } .footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; } .footnotes + .footnotes { margin-top: 0px; } .md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; } li div { padding-top: 0px; } blockquote { margin: 1rem 0px; } li .mathjax-block, li p { margin: 0.5rem 0px; } li blockquote { margin: 1rem 0px; } li { margin: 0px; position: relative; } blockquote > :last-child { margin-bottom: 0px; } blockquote > :first-child, li > :first-child { margin-top: 0px; } .footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; } #write .footnote-line { white-space: pre-wrap; } @media print { body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; } #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; } .typora-export * { -webkit-print-color-adjust: exact; } .typora-export #write { break-after: avoid; } .typora-export #write::after { height: 0px; } .is-mac table { break-inside: avoid; } .typora-export-show-outline .typora-export-sidebar { display: none; } } .footnote-line { margin-top: 0.714em; font-size: 0.7em; } a img, img a { cursor: pointer; } pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; } p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; } #write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; } p > .md-image:only-child { display: inline-block; width: 100%; } #write .MathJax_Display { margin: 0.8em 0px 0px; } .md-math-block { width: 100%; } .md-math-block:not(:empty)::after { display: none; } .MathJax_ref { fill: currentcolor; } [contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; } .md-task-list-item { position: relative; list-style-type: none; } .task-list-item.md-task-list-item { padding-left: 0px; } .md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; } .math { font-size: 1rem; } .md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; } .md-toc-content { position: relative; margin-left: 0px; } .md-toc-content::after, .md-toc::after { display: none; } .md-toc-item { display: block; color: rgb(65, 131, 196); } .md-toc-item a { text-decoration: none; } .md-toc-inner:hover { text-decoration: underline; } .md-toc-inner { display: inline-block; cursor: pointer; } .md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; } .md-toc-h2 .md-toc-inner { margin-left: 2em; } .md-toc-h3 .md-toc-inner { margin-left: 4em; } .md-toc-h4 .md-toc-inner { margin-left: 6em; } .md-toc-h5 .md-toc-inner { margin-left: 8em; } .md-toc-h6 .md-toc-inner { margin-left: 10em; } @media screen and (max-width: 48em) { .md-toc-h3 .md-toc-inner { margin-left: 3.5em; } .md-toc-h4 .md-toc-inner { margin-left: 5em; } .md-toc-h5 .md-toc-inner { margin-left: 6.5em; } .md-toc-h6 .md-toc-inner { margin-left: 8em; } } a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; } .footnote-line a:not(.reversefootnote) { color: inherit; } .md-attr { display: none; } .md-fn-count::after { content: "."; } code, pre, samp, tt { font-family: var(--monospace); } kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; } .md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); } code { text-align: left; } a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; } .os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; } .md-diagram-panel > svg { max-width: 100%; } [lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; } [lang="mermaid"] .node text { font-size: 1rem; } table tr th { border-bottom-width: 0px; } video { max-width: 100%; display: block; margin: 0px auto; } iframe { max-width: 100%; width: 100%; border: none; } .highlight td, .highlight tr { border: 0px; } mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); } .md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; } .md-expand mark .md-meta { opacity: 0.3 !important; } mark .md-meta { color: rgb(0, 0, 0); } @media print { .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; } } .md-diagram-panel .messageText { stroke: none !important; } .md-diagram-panel .start-state { fill: var(--node-fill); } .md-diagram-panel .edgeLabel rect { opacity: 1 !important; } .md-require-zoom-fix { height: auto; margin-top: 16px; margin-bottom: 16px; } .md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); } .md-fences.md-fences-math { font-size: 1em; } .md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; } .md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; } .typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; } .typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; } .typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; } @media screen and (max-width: 1024px) { .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; } } @media screen and (max-width: 800px) { .typora-export-sidebar { display: none; } } .outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; } .outline-content ul { margin-top: 0px; margin-bottom: 0px; } .outline-content strong { font-weight: 400; } .outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; } .outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; } .outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; } .outline-expander:hover::before { content: ''; } .outline-h1 > .outline-item { padding-left: 0px; } .outline-h2 > .outline-item { padding-left: 1em; } .outline-h3 > .outline-item { padding-left: 2em; } .outline-h4 > .outline-item { padding-left: 3em; } .outline-h5 > .outline-item { padding-left: 4em; } .outline-h6 > .outline-item { padding-left: 5em; } .outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; } .outline-label:hover { text-decoration: underline; } .outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); } .outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; } .outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; } .outline-item-open > .outline-item > .outline-expander::before { content: ''; } .outline-children { display: none; } .info-panel-tab-wrapper { display: none; } .outline-item-open > .outline-children { display: block; } .typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; } .typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; } .typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; } .typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; } .typora-export-collapse-outline .outline-children { display: none; } .typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; } .typora-export-no-collapse-outline .outline-expander::before { content: "" !important; } .typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; } .md-inline-math-container mjx-container { zoom: 0.95; } :root { --side-bar-bg-color: #fafafa; --control-text-color: #777; } @include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext); /* open-sans-regular - latin-ext_latin */ /* open-sans-italic - latin-ext_latin */ /* open-sans-700 - latin-ext_latin */ /* open-sans-700italic - latin-ext_latin */ html { font-size: 16px; -webkit-font-smoothing: antialiased; } body { font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, 'Segoe UI Emoji', sans-serif; color: rgb(51, 51, 51); line-height: 1.6; } #write { max-width: 860px; margin: 0 auto; padding: 30px; padding-bottom: 100px; } @media only screen and (min-width: 1400px) { #write { max-width: 1024px; } } @media only screen and (min-width: 1800px) { #write { max-width: 1200px; } } #write > ul:first-child, #write > ol:first-child{ margin-top: 30px; } a { color: #4183C4; } h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid #eee; } h2 { font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid #eee; } /*@media print { .typora-export h1, .typora-export h2 { border-bottom: none; padding-bottom: initial; } .typora-export h1::after, .typora-export h2::after { content: ""; display: block; height: 100px; margin-top: -96px; border-top: 1px solid #eee; } }*/ h3 { font-size: 1.5em; line-height: 1.43; } h4 { font-size: 1.25em; } h5 { font-size: 1em; } h6 { font-size: 1em; color: #777; } p, blockquote, ul, ol, dl, table{ margin: 0.8em 0; } li>ol, li>ul { margin: 0 0; } hr { height: 2px; padding: 0; margin: 16px 0; background-color: #e7e7e7; border: 0 none; overflow: hidden; box-sizing: content-box; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul:first-child, ol:first-child { margin-top: 0; } ul:last-child, ol:last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dfe2e5; padding: 0 15px; color: #777777; } blockquote blockquote { padding-right: 0; } table { padding: 0; word-break: initial; } table tr { border: 1px solid #dfe2e5; margin: 0; padding: 0; } table tr:nth-child(2n), thead { background-color: #f8f8f8; } table th { font-weight: bold; border: 1px solid #dfe2e5; border-bottom: 0; margin: 0; padding: 6px 13px; } table td { border: 1px solid #dfe2e5; margin: 0; padding: 6px 13px; } table th:first-child, table td:first-child { margin-top: 0; } table th:last-child, table td:last-child { margin-bottom: 0; } .CodeMirror-lines { padding-left: 4px; } .code-tooltip { box-shadow: 0 1px 1px 0 rgba(0,28,36,.3); border-top: 1px solid #eef2f2; } .md-fences, code, tt { border: 1px solid #e7eaed; background-color: #f8f8f8; border-radius: 3px; padding: 0; padding: 2px 4px 0px 4px; font-size: 0.9em; } code { background-color: #f3f4f4; padding: 0 2px 0 2px; } .md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; } .md-task-list-item > input { margin-left: -1.3em; } @media print { html { font-size: 13px; } table, pre { page-break-inside: avoid; } pre { word-wrap: break-word; } } .md-fences { background-color: #f8f8f8; } #write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: #f7f7f7; border: 0; border-radius: 3px; color: #777777; margin-top: 0 !important; } .mathjax-block>.code-tooltip { bottom: .375rem; } .md-mathjax-midline { background: #fafafa; } #write>h3.md-focus:before{ left: -1.5625rem; top: .375rem; } #write>h4.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h5.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h6.md-focus:before{ left: -1.5625rem; top: .285714286rem; } .md-image>.md-meta { /*border: 1px solid #ddd;*/ border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; } .md-tag { color: #a7a7a7; opacity: 1; } .md-toc { margin-top:20px; padding-bottom:20px; } .sidebar-tabs { border-bottom: none; } #typora-quick-open { border: 1px solid #ddd; background-color: #f8f8f8; } #typora-quick-open-item { background-color: #FAFAFA; border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; border-style: solid; border-width: 1px; } /** focus mode */ .on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); } header, .context-menu, .megamenu-content, footer{ font-family: "Segoe UI", "Arial", sans-serif; } .file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state{ visibility: visible; } .mac-seamless-mode #typora-sidebar { background-color: #fafafa; background-color: var(--side-bar-bg-color); } .md-lang { color: #b4654d; } /*.html-for-mac { --item-hover-bg-color: #E6F0FE; }*/ #md-notification .btn { border: 0; } .dropdown-menu .divider { border-color: #e5e5e5; opacity: 0.4; } .ty-preferences .window-content { background-color: #fafafa; } .ty-preferences .nav-group-item.active { color: white; background: #999; } .menu-item-container a.menu-style-btn { background-color: #f5f8fa; background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); } :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} 目录 技术概要: Globals 1 什么是 Globals? 1 为什么要学习 Globals? 1 试一试: 访问 Globals 的三种方式 2 用前须知 2 导入和检查类定义 2 导入示例数据并检查 Globals 3 关系访问 Globals(Accessing Globals Relationaly) 5 将 Globals 作为对象访问(Accessing Globals as Objects) 6 直接访问 Globals(Accessing Globals Directly) 7 有关 Globals 的更多信息 8 使用 InterSystems IRIS API 访问 Globals 9 了解有关 Globals 的更多信息 10 Globals 及其结构 10 多模型开发 10 InterSystems Native API 10 技术概要: Globals 本文档向您介绍了 globals 的概念,globals是 InterSystems IRIS®数据平台的底层存储结构。我们将向您展示如何使用关系模型和对象模型访问 globals,以及如何直接访问 globals。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些 ,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 什么是 Globals? InterSystems IRIS 数据平台的特点之一是它能够一次性存储数据,并允许您使用多个范式(paradigm)来访问它。例如,您可以使用 InterSystems SQL 将数据可视化为行和列,或者您可以使用 ObjectScript 将数据视为具有属性和方法的对象。您的应用程序甚至可以混合使用这两种数据模型,对于给定的任务使用最简单和更有效的模型。但是无论您如何访问数据,InterSystems IRIS 都将其存储在被称为 globals 的底层数据结构中。 Globals 可以被认为是持久化多维稀疏数组(persistent multidimensional sparse arrays): 持久化(Persistent)------Globals 存储在数据库中,可以在任何时候被任何可以访问该数据库的进程(process)检索到。 多维(Multidimensional)------global 节点可以有任意数量的下标。这些下标可以是整数、小数,或字符串。 稀疏(Sparse)------节点下标不必是连续的,这意味着没有存储值的下标不会使用任何存储。 Global 节点可以存储多种类型的数据,包括: 字符串 数字数据 字符或二进制数据流 数据集合,如列表或数组 对其他存储位置的引用 即使是您编写的服务器端代码,最终也存储在 globals 中! 为什么要学习 Globals? 在了解很少或几乎不了解 globals 的情况下,虽然也可以在 InterSystems IRIS 平台上编写应用程序,但出于以下几个原因,您可能想了解有关它们的更多信息: 如果您直接访问 globals,有些操作可能会更容易或更有效。 您可能希望为不符合关系或对象数据模型的数据创建自定义数据结构。 试一试: 访问 Globals 的三种方式 有些系统管理任务是在 global 层面完成的,了解 globals 将使这些任务对您更有意义。 试一试:访问 Globals 的三种方式 在本文档中,您将检查用于存储 U.S. 州类对象的数据的 globals。该类的属性包括州名、双字母邮政缩写、首府、建州年份和面积(单位:平方英里)。然后,您将使用关系和对象技术,以及直接操作 globals 来访问和存储这个类的对象。 用前须知 要使用这个技术概要(First Look),您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括几种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管您的系统必须能够通过网络访问该实例)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。 您也需要知道: 实例的基于 web 的管理门户(Management Portal)的 URL,这是 InterSystems IRIS 的系统管理用户界面。 如何访问终端(Terminal),InterSystems IRIS 命令行工具。 实例的用户名和密码(InterSystems Labs 上的 web 实例不需要)。 您还需要从 InterSystems GitHub repo :https://github.com/intersystems/First- Look-Globals 下载两个示例文件。 FirstLookGlobals.xml 包含 State 类的类定义。 FirstLookGlobals.gof 包含了 U.S. 最初 13 个州的一些 global 示例数据。 关于如何访问管理门户(Management Portal )或终端(Terminal)的更多信息,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的"InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)"。您实际上并不需要一个 IDE 来做这些练习。 导入和检查类(Class)定义 首先,将 State 类定义导入 InterSystems IRIS: 从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > Classes(类)。 在 Classes 页面上,查看左栏,确保您在 USER 命名空间。您可以把命名空间看作是工作空间或目录。 点击 Import(导入)。 在 Import Classes 的对话框中: a. 如果您的 InterSystems IRIS 实例在远程服务器上运行,请指定是将示例文件下载到远程服务器还是下载到您的本地计算机。 b. 在 File 或 Directory 的 Import(导入)区域,点击 File(文件)。 c. 浏览您从 GitHub 下载的 FirstLookGlobals.xml 文件。 试一试: 访问 Globals 的三种方式 d. 选择 Compile Imported Items(编译导入项)。 e. 对于 Compile Flags(编译标志),指定 cuk。 f. 点击 Next(下一步)。 g. 点击 Import(导入)。 h. 当出现加载成功的消息时,点击 Done(完成)。 现在,在 Classes 页面,您应该看到 FirstLook.State.cls 在类的列表中。在 InterSystems IRIS 中,包含类的包名称(FirstLook)附加有类的名称(State)。扩展名 .cls 用来表示类文件。 注意: 如果您的命名空间包含大量的类,可以在页面左栏的 Class Name(类名) 框中输入 F*.cls 来过滤列表。 在 FirstLook.State.cls 类的右侧,点击 Documentation(文档) 来查看为该类生成的文档。 您会注意到的第一件事是 FirstLook.State 类扩展了 %Persistent 类,这意味着该类的数据将存储在数据库中 (系统定义的类和方法通常以 % 开头) 。 persistent class FirstLook.State extends %Persistent 扩展 %Persistent 还提供了一些方法,您可以使用这些方法在该类上执行操作。例如,它允许您创建该类的新对象或从数据库访问对象并将其加载到内存中。 再往下看,您可以看到这个类有五个属性:Area、Capital、Established、Name 和 PostalAbbr。 property Area as %Integer; property Capital as %String; property Established as %Integer; property Name as %String [ Required ]; property PostalAbbr as %String; 这个类还有两个索引,CapitalIndex 和 PostalAbbrIndex,这两个索引可以加快 SQL 查询的速度,并允许您通过首府和邮政缩写快速查找州。 index (CapitalIndex on Capital) [Unique]; index (PostalAbbrIndex on PostalAbbr) [Unique]; 导入示例数据并检查 Globals 要了解存储 State 类对象的 globals,首先要导入一些数据: 从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > Globals。(或从 Classes 页面,点击 Globals 按钮。) 在 Globals 页面上,查看左栏,确保您在 USER 命名空间。 点击 Import(导入)。 在 Import Globals 对话框中: a. 如果您的 InterSystems IRIS 实例在远程服务器上运行,请指定是将示例文件下载到远程服务器还是下载到您的本地计算机。 b. 浏览您从 GitHub 下载的 FirstLookGlobals.gof 文件。 c. 点击 Next(下一步)。 d. 点击 Import(导入)。 试一试: 访问 Globals 的三种方式 e. 当出现加载成功的消息时,点击 Done(完成)。 现在,在 Globals 页面上,您应该看到 FirstLook.StateD 和 FirstLook.StateI 这两个 globals 在列表中。默认情况下,类(class)的数据存储在名称后面加 Dappended 的 global 中,索引存储在名称后面加 Iappended 的 global 中。最常见的情况是,您会看到 globals 名称前有一个插入符号(\^)。 注意: 如果您的命名空间包含大量的 globals,可以在页面左栏的 Global Name(Global 名称) 框中输入 F* 来过滤这个列表。 在 FirstLook.StateD global 的右边,点击 View(查看) 来显示 global 内容的列表。 \^FirstLook.StateD = 13 \^FirstLook.StateD(1) = $lb("","Delaware","DE","Dover",1787,2489) \^FirstLook.StateD(2) = $lb("","Pennsylvania","PA","Harrisburg",1787,46054) \^FirstLook.StateD(3) = $lb("","New Jersey","NJ","Trenton",1787,8723) \^FirstLook.StateD(4) = $lb("","Georgia","GA","Atlanta",1788,59425) \^FirstLook.StateD(5) = $lb("","Connecticut","CT","Hartford",1788,5543) \^FirstLook.StateD(6) = $lb("","Massachusetts","MA","Boston",1788,10554) \^FirstLook.StateD(7) = $lb("","Maryland","MD","Annapolis",1788,12406) \^FirstLook.StateD(8) = $lb("","South Carolina","SC","Columbia",1788,32020) \^FirstLook.StateD(9) = $lb("","New Hampshire","NH","Concord",1788,9349) \^FirstLook.StateD(10) = $lb("","Virginia","VA","Richmond",1788,42775) \^FirstLook.StateD(11) = $lb("","New York","NY","Albany",1788,54555) \^FirstLook.StateD(12) = $lb("","North Carolina","NC","Raleigh",1789,53819) \^FirstLook.StateD(13) = $lb("","Rhode Island","RI","Providence",1790,1545) 您可以看到,每个状态的节点都有一个整数的下标,称为对象 ID(或简称 ID),它是在您存储这个类的新对象时由系统生成的。Global 的根节点,没有下标,包含一个计数器,该计数器递增以生成下一个 ID。 每个节点的数据按照在类定义中指定的顺序存储为属性列表。如果查看 \^FirstLook.StateD(3),您可以看到州名是新泽西州(New Jersey),邮政缩写是 NJ,首府是特伦顿(Trenton),该州于 1787 年加入联邦(Union),面积为 8723 平方英里。 点击 Cancel(取消) 返回 globals 列表,然后点击 global FirstLook.StateI 旁边的 View(查看) 查看 State 类的索引。 \^FirstLook.StateI("CapitalIndex"," ALBANY",11) = "" \^FirstLook.StateI("CapitalIndex"," ANNAPOLIS",7) = "" \^FirstLook.StateI("CapitalIndex"," ATLANTA",4) = "" \^FirstLook.StateI("CapitalIndex"," BOSTON",6) = "" \^FirstLook.StateI("CapitalIndex"," COLUMBIA",8) = "" \^FirstLook.StateI("CapitalIndex"," CONCORD",9) = "" \^FirstLook.StateI("CapitalIndex"," DOVER",1) = "" \^FirstLook.StateI("CapitalIndex"," HARRISBURG",2) = "" \^FirstLook.StateI("CapitalIndex"," HARTFORD",5) = "" \^FirstLook.StateI("CapitalIndex"," PROVIDENCE",13) = "" \^FirstLook.StateI("CapitalIndex"," RALEIGH",12) = "" \^FirstLook.StateI("CapitalIndex"," RICHMOND",10) = "" \^FirstLook.StateI("CapitalIndex"," TRENTON",3) = "" \^FirstLook.StateI("PostalAbbrIndex"," CT",5) = "" \^FirstLook.StateI("PostalAbbrIndex"," DE",1) = "" \^FirstLook.StateI("PostalAbbrIndex"," GA",4) = "" \^FirstLook.StateI("PostalAbbrIndex"," MA",6) = "" \^FirstLook.StateI("PostalAbbrIndex"," MD",7) = "" \^FirstLook.StateI("PostalAbbrIndex"," NC",12) = "" \^FirstLook.StateI("PostalAbbrIndex"," NH",9) = "" \^FirstLook.StateI("PostalAbbrIndex"," NJ",3) = "" \^FirstLook.StateI("PostalAbbrIndex"," NY",11) = "" \^FirstLook.StateI("PostalAbbrIndex"," PA",2) = "" \^FirstLook.StateI("PostalAbbrIndex"," RI",13) = "" \^FirstLook.StateI("PostalAbbrIndex"," SC",8) = "" \^FirstLook.StateI("PostalAbbrIndex"," VA",10) = "" 仔细看看 global \^FirstLook.StateI 中的第一个节点。这里,第一个下标("CapitalIndex")是索引的名称,第二个下标是被索引的属性的值("ALBANY"),第三个下标是以奥尔巴尼(Albany)为首府的州的 ID(11)。如果您回顾一下 global 数据,您会发现 \^FirstLook.StateD(11) 是纽约州(New York)。 Globals 使用数组下标自动按排序顺序存储。 试一试: 访问 Globals 的三种方式 关系访问 Globals (Accessing Globals Relationally) 现在,看看为 State 类生成的 InterSystems IRIS 表: 从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > SQL。 在 SQL 页面上,查看页面的顶部,确保您在 USER 名称空间。 如果不是,请点击 Switch(切换)来改更改命名空间。 在左栏中,展开 Tables(表)部分来查看命名空间中的表。 在 Tables 下,点击 FirstLook.State 表。 在 Catalog Details(目录详情) 标签上,点击 Fields(字段),您将看到为 State 类的每个属性生成的字段,以及称为 ID(有时称为 RowID) 的额外字段。 这个字段类似于您在类的 globals 中看到的对象 ID。 注意: 如果您的命名空间包含大量的表,可以在页面左栏的 Filter(过滤) 框中输入 F* 来过滤列表。 点击 Execute Query(执行查询) 标签,打开一个文本区,您可以在这里编写针对 FirstLook.State 表运行的查询。 输入以下查询: SELECT * FROM FirstLook.State WHERE ID = 6 并点击 Execute(执行)。该查询返回您请求的马萨诸塞州(Massachusetts )的行。 输入以下查询: INSERT INTO FirstLook.State(Area, Capital, Established, Name, PostalAbbr) VALUES (9616, 'Montpelier', 1791, 'Vermont', 'VT') 并点击 Execute(执行),将一行插入第 14 个州佛蒙特州(Vermont )的表中。 要查看在 FirstLook.State 表中插入一行的效果,请返回到命名空间 USER 的 Globals 页面,并再次查看 globals。 从管理门户(Management Portal)的主页,选择 System Explorer(系统资源管理器) > Globals。 在 Globals 页面上,查看左栏,确保您在 USER 命名空间。 查看数据 global,\^FirstLook.StateD,您可以看到 ID 计数器已经增加: \^FirstLook.StateD = 14 并且一个新的节点被添加到 global: \^FirstLook.StateD(14) = $lb("","Vermont","VT","Montpelier",1791,9616) 查看索引 global,\^FirstLook.StateI,可以看到索引已经被更新为两个新节点: \^FirstLook.StateI("CapitalIndex"," MONTPELIER",14) = "" 和 \^FirstLook.StateI("PostalAbbrIndex"," VT",14) = "" 试一试: 访问 Globals 的三种方式 将 Globals 作为对象访问(Accesing Globals as Objects) 请记住,当您创建 State 类时,扩展了类 %Persistent,这使您可以访问一些有用的方法,这些方法使您可以在类的 globals 中存储数据并再次检索它。接下来,通过在 InterSystems 终端(Terminal)中编写一些 ObjectScript 来测试其中一些方法。如果您以前没有使用过终端(Terminal),请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的"InterSystems IRIS Connection Information(InterSystems IRIS 连接信息"。 在您启动 Terminal session (终端会话)后,您应该看到一个提示符,指示您所处的名称空间。如果您不在 USER 命名空间,执行以下命令: set $namespace = "USER" 首先,将您刚刚用 SQL 查询添加的佛蒙特州(Vermont)的数据加载到内存中。调用 FirstLook.State 类的 %OpenId() 方法,并将返回值赋给变量 vt。%OpenId() 返回对象的"句柄(handle)",更正式地称为对象引用或 OREF。 USER>set vt = ##class(FirstLook.State).%OpenId(14) 您可以通过访问对象的 Name 属性来查看刚刚加载的状态的名称: USER>write vt.Name Vermont 您可以使用 zwrite 命令获取所有对象属性的摘要。该命令提供的其他信息超出了本文档的范围。 USER>zwrite vt vt=2@FirstLook.State ; <OREF> +----------------- general information --------------- | oref value: 2 | class name: FirstLook.State | %%OID: $lb("14","FirstLook.State") | reference count: 2 +----------------- attribute values ------------------ | %Concurrency = 1 <Set> | Area = 9616 | Capital = "Montpelier" | Established = 1791 | Name = "Vermont" | PostalAbbr = "VT" +----------------------------------------------------- 要创建一个新的 State 对象,请使用 %New() 方法,该方法将一个 OREF 返回给新对象。 USER>set newstate = ##class(FirstLook.State).%New() 现在,设置第 15 个州肯塔基州(Kentucky)的属性。USER>set newstate.Name = "Kentucky" USER>set newstate.PostalAbbr = "KY" USER>set newstate.Capital = "Frankfort" USER>set newstate.Established = 1792 USER>set newstate.Area = 40408 检查所有属性。 试一试: 访问 Globals 的三种方式 USER>zwrite newstate newstate=4@FirstLook.State ; <OREF> +----------------- general information --------------- | oref value: 4 | class name: FirstLook.State | reference count: 2 +----------------- attribute values ------------------ | %Concurrency = 1 <Set> | Area = 40408 | Capital = "Frankfort" | Established = 1792 | Name = "Kentucky" | PostalAbbr = "KY" +----------------------------------------------------- 如果您对一切看起来很满意,通过调用新对象的 %Save() 方法将对象保存到磁盘。%Save() 方法返回一个状态,如果保存成功,该状态的值为 1。 USER>set status = newstate.%Save() USER>write status 1 再一次,通过进入管理门户(Management Portal)中的 Globals 页面来检查您的工作。查看数据 global, \^FirstLook.StateD,您可以看到 ID 计数器再次增加: \^FirstLook.StateD = 15 并且一个新的节点被添加到 global: \^FirstLook.StateD(15) = $lb("","Kentucky","KY","Frankfort",1792,40408) 查看索引 global,\^FirstLook.StateI,可以看到索引已经被更新为两个新节点: \^FirstLook.StateI("CapitalIndex"," FRANKFORT",15) = "" 和 \^FirstLook.StateI("PostalAbbrIndex"," KY",15) = "" 直接访问 Globals(Accessing Globals Directly) 虽然 InterSystems IRIS 中的数据最常见的是通过 SQL 或使用对象层来访问,但您也可以直接访问扩展 %Persistent 的类的 globals。这种方法比较棘手,因为您需要知道 global 的结构。 首先,找到 ID 为 15 的州名称。 在终端(Terminal)中,用下标 15 将变量 ky 赋给数据 global 中的节点。 USER>set ky = \^FirstLook.StateD(15) 您可以使用 zwrite 检查存储在这个节点上的值: USER>zwrite ky ky=$lb("","Kentucky","KY","Frankfort",1792,40408) 接下来,使用 $list() 函数来获取列表中的第二项: USER>write $list(ky, 2) Kentucky 根据您在使用 SQL 或对象方法添加状态后检查 globals 所学到的内容,编写一些代码来添加新状态。 首先,准备数据,将每个属性(从对象的角度考虑)或字段(从 SQL 的角度考虑)放入不同的变量。 试一试: 访问 Globals 的三种方式 USER>set name = "Tennessee" USER>set postalabbr = "TN" USER>set capital = "Nashville" USER>set established = 1796 USER>set area = 42144 然后使用 $listbuild() 函数构建可以存储的属性列表。 USER>set properties = $listbuild("", name, postalabbr, capital, established, area) USER>zwrite properties properties=$lb("","Tennessee","TN","Nashville",1796,42144) 使用一个 ObjectScript 语句,增加 \^FirstLook.StateD global 的 ID 计数器,并将新值赋给变量 id。 USER>set id = $increment(\^FirstLook.StateD) USER>write \^FirstLook.StateD 16 USER>write id 16 现在,将数据存储在数据 global 中。 USER>set \^FirstLook.StateD(id) = properties USER>zwrite \^FirstLook.StateD(id) \^FirstLook.StateD(16)=$lb("","Tennessee","TN","Nashville",1796,42144) 现在我们需要手动更新索引,否则在首府(Capital )或邮政缩写(PostalAbbr)上,带有 WHERE 子句的 SQL 查询将不包括田纳西州(Tennessee)。这个过程比存储数据要复杂一些。 对于字符串值(string value)的索引,InterSystems IRIS 将字符串转换为大写字母,并在前面添加一个空格字符,以便于排序。使用 _运算符将一个空格连接到大写字母的前面,然后使用 $zconvert() 函数将其转换为大写字母。然后对邮政缩写执行相同操作。 USER>set capital = $zconvert(" "_capital, "U") USER>set postalabbr = $zconvert(" "_postalabbr, "U") 最后,将索引条目存储在索引 global 中。 USER>set \^FirstLook.StateI("CapitalIndex", capital, id) = "" USER>set \^FirstLook.StateI("PostalAbbrIndex", postalabbr, id) = "" 为确保您正确完成工作,请进入管理门户(Management Portal)中的 Globals 页面,并查看 \^FirstLook.StateD 和 \^FirstLook.StateI globals。您也可以使用 zwrite \^FirstLook.StateD 和 zwrite \^FirstLook.StateI 从终端(Terminal)显示每个 global 的完整内容。 有关 Globals 的更多信息 使用 SQL 创建 Globals 在本文档中,您所看到的 globals 是通过存储使用类定义(class definition)指定的类的对象(object)创建的。您可以通过使用 SQL 创建表和表的索引来创建结构非常相似的 globals。然后,InterSystems IRIS 将根据您创建的表为您生成一个类。 作为练习,进入管理门户(Management Portal)中 USER 命名空间的 SQL 页面,并使用 Execute Query(执行查询)标签执行下列语句。 使用 InterSystems IRIS API 访问 Globals CREATE TABLE FirstLook.SQL (%CLASSPARAMETER USEEXTENTSET 0, %CLASSPARAMETER DEFAULTGLOBAL = '\^FirstLook.SQL', Name CHAR(30) NOT NULL, PostalAbbr CHAR(2), Capital CHAR(30), Established INT, Area INT) CREATE UNIQUE INDEX CapitalIndex ON FirstLook.SQL (Capital) CREATE UNIQUE INDEX PostalAbbrIndex ON FirstLook.SQL (PostalAbbr) INSERT INTO FirstLook.SQL (Name, PostalAbbr, Capital, Established, Area) VALUES ('Maine', 'ME', 'Augusta', 1820, 35380) 在 SQL 页面的左栏中,您现在应该看到 FirstLook.SQL 表。 进入 Classes 页面,找到类 FirstLook.SQL.cls 并查看其文档。您注意到有什么不同吗?这个类有一个额外的索引,称为位图扩展索引(Bitmap Extent Index)。然后进入 Globals 页面,找到 \^FirstLook.SQLD 和 \^FirstLook.SQLI globals。看看 \^FirstLook.SQLI,并看看您是否能找到额外的索引。 创建自定义 Globals 到目前为止,您已经看到了扩展 %Persistent 类时创建的 globals。但是,globals 可用于存储无模式的数据,这些数据可能不适合类或关系范式。例如,使用终端(Terminal)或管理门户(Management Portal),切换到 %SYS 命名空间,并检查 \^CONFIGglobal,它存储了一些 InterSystems IRIS 配置设置。下面是 \^CONFIGglobal 示例的一部分: \^CONFIG("Cluster","CommIPAddress") = "" \^CONFIG("Cluster","JoinCluster") = 0 \^CONFIG("ConfigFile","Version") = "2018.20" \^CONFIG("Conversions","LastConvertTime") = "2019-03-13 08:39:45" \^CONFIG("Databases","ENSLIB") = "/usr/irissys/mgr/enslib/" \^CONFIG("Databases","IRISAUDIT") = "/usr/irissys/mgr/irisaudit/" \^CONFIG("Databases","IRISLIB") = "/usr/irissys/mgr/irislib/" \^CONFIG("Databases","IRISLOCALDATA") = "/usr/irissys/mgr/irislocaldata/" \^CONFIG("Databases","IRISSYS") = "/usr/irissys/mgr/" \^CONFIG("Databases","IRISTEMP") = "/usr/irissys/mgr/iristemp/" \^CONFIG("Databases","USER") = "/usr/irissys/mgr/user/" 如果您想创建和存储自己的自定义数据结构,您可以使用 ObjectScript 轻松做到。使用下面的示例,您可以编写几行代码定义一个有向图来存储机场之间的机票价格: USER>set \^Fares("BOS", "ORD") = 87 USER>set \^Fares("ORD", "BOS") = 63 USER>set \^Fares("BOS", "LAX") = 143 USER>set \^Fares("LAX", "BOS") = 143 USER>set \^Fares("ORD", "LAX") = 57 USER>set \^Fares("LAX", "ORD") = 94 USER>zwrite \^Fares \^Fares("BOS","LAX")=143 \^Fares("BOS","ORD")=87 \^Fares("LAX","BOS")=143 \^Fares("LAX","ORD")=94 \^Fares("ORD","BOS")=63 \^Fares("ORD","LAX")=57 使用 InterSystems IRIS API 访问 Globals 如果您正在用 Java、.NET、Node.js 或 Python 编写应用程序,InterSystems IRIS 提供的 API 允许您使用本文中讨论的三种模型来操作您的数据库: 通过 JDBC、ADO.NET 或 PyODBC API 进行关系访问 通过 InterSystems XEP API 访问对象 通过 InterSystems Native API 直接访问 globals 了解有关 Globals 的更多信息 现在您知道了,无论您决定如何存储或访问数据,您所做的就是使用 globals。 注意: 并非所有语言都支持所有形式的访问。 了解有关 Globals 的更多信息 使用下面列出的参考资料来了解更多有关 globals 和如何访问它们的信息。 Globals 及其结构 Globals QuickStart(Globals 快速入门)------提供 global 结构的可视化视图,并给出在自定义 global 结构中存储数据的示例。 Using Globals(《使用 Globals》)------讨论 Globals 的结构、如何管理它们以及如何使用 SQL 或 ObjectScript 访问它们。 Globals------Defining and Using Classes(定义和使用类)这部分解释了为扩展 %Persistent 类的类创建的 globals 的命名约定。 多模型开发 Multi-Model QuickStart(多模型快速入门)------描述了 InterSystems IRIS 如何允许您用各种不同的语言(包括 Java、.NET 和 ObjectScript)使用您选择的数据模型。 Java QuickStart(Java 快速入门)------向您展示如何使用 Java API 对 InterSystems IRIS 数据库进行关系、对象和直接访问。 .NET QuickStart(.NET 快速入门)------向您展示如何使用 .NET API 对 InterSystems IRIS 数据库进行关系、对象和直接访问。 Python QuickStart(Python 快速入门)------向您展示如何使用 Python API 对 InterSystems IRIS 数据库进行关系、对象和直接访问。 InterSystems Native API Using the Native API for Java(《使用 Native API for Java》) (交互式课程)------向您展示如何使用 Native API for Java 访问 globals 以及调用类方法(call class method)和例程。 Using the Native API for Java(《使用 Native API for Java 》)(书籍)------向您展示如何使用 Native API for Java 访问 globals 以及调用类方法(call class method)和例程。 First Look: InterSystems IRIS Native API for Java(《技术概要:InterSystems IRIS Native API for Java》) --- 展示如何从 Java 应用程序访问 InterSystems IRIS globals。 Using the Native API for .NET(《使用 Native API for .NET》 )(交互式课程)------向您展示如何使用 Native API for .NET 访问 globals 以及调用类方法(call class method)和例程。 Using the InterSystems Native API for .NET(《使用 InterSystems Native API for .NET》)(书籍)------向您展示如何使用 Native API for .NET 访问 globals 以及调用类方法(call class method)和例程。 First Look: InterSystems IRIS Native API for .NET(《技术概要:InterSystems IRIS Native API for .NET》) ------展示如何从 .NET 应用程序访问 InterSystems IRIS globals。 了解有关 Globals 的更多信息 Node.js QuickStart(Node.js 快速入门)------向您展示如何使用 Native API for Node.js 访问 globals 以及调用类方法(call class method)和例程。 Using the Native API for Node.js(《使用 Native API for Node.js》)------向您展示如何使用 Native API for Python 访问 globals 以及调用类方法(call class method)和例程。 First Look: InterSystems IRIS Native API for Node.js(《技术概要:InterSystems IRIS Native API for Node.js》)-展示如何从 Node.js 应用程序访问 InterSystems IRIS globals。 Using the Native API for Python(《使用 Native API for Python》) (交互式课程)------向您展示如何使用 Native API for Python 访问 globals 以及调用类方法(call class method)和例程。 Using the Native API for Python(《使用 Native API for Python》) (书籍)------向您展示如何使用 Native API for Python 访问 globals 以及调用类方法(call class method)和例程。 First Look: InterSystems IRIS Native API for Python(《技术概要:InterSystems IRIS Native API for Python》)------展示如何从 Python 应用程序访问 InterSystems IRIS globals。