Framework/Another Lore2009. 4. 30. 10:48


Wokrspace의 Security의 문제
현재 AL Workspace의 보안 Role 모델은 Window의 탐색기로 시작했다. 
각각의 컴퓨터의 탐색기는 별도의 Root를 가지고 모든 파일을 TreePath로 접근할수 있다.

Storage가 물리적인 의미인 반면에 Workspace는 물리적이 아니라 논리적인 의미이다.

A컴퓨터를 GroupA와 GroupB사용자가 하나의 Storage로 각각 다른 Workspace를 사용할때(하나의 Storage를 2개 이상의 Workspace로 사용할때) GroupA와 GroupB는 별도의 TreePath를 가지며 각각의 Workspace에서 TreePath는 유니크하다. 여기까지는 문제가 없다.

단 Node의 UUID로 접근할때 이를 허용해야 하는가의 문제이다. 이를 허용하면 Workspace가 물리적으로 나뉘어 있을때도 접근을 허용해야 하는 문제가 있다. 허용하지 않으려면 매번 WorkspaceName을 검사해야 한다. 이 문제는 일반적인 규악이 없고 Workspace간의 SharableNode의 문제와 얽히기 때문에 머리에서 쥐가 난다.


프로그램에는 How의 코딩의 문제를 벗어나게 되면 일반적으로 2가지 문제가 있는데 하나는 다른 이해 관계자와 커뮤니케이션의 문제이고 두번째는 무엇(What)을 해야 하는가이다. 이런 종류는 방법이 없는게 문제가 아니라 방법이 너무 많아서 어느게 가장 좋은 방법인가를 지금은 알지 못한다에 문제가 있다.


이 문제를 bleujin식 난제 네이밍관례에 따라 "아들을 아들이라 부르지 못하고.." 문제로 정의하였다.




AL은 국제화
AL은 OR Mapping이 아닌 Repository에 가깝기 때문에 UTF인코딩을 넘어서는 국제화를 지원해야 한다.

이를테면 우리나라는 GMT+9의 Timezone에 있다. 날짜는 절대시간으로서의 인식과 상대시간으로의 인식이 있는데 오스트리아의 오늘 일몰 시간은 오후 07:13분입니다 라고 할때는 절대시간으로서 저장해야 하고 오스트리아의 오후 7시 13분이 우리나라 시간으로 몇시지? 라고 생각하면 상대시간으로 저장해야 한다.

그러나 시간은 말하지 않기 때문에 사용자가 Property에 날짜값을 설정했을때 어느 시간으로 저장해야 하는가에 대한 문제가 있다. 이를테면 호주에서 4월 30일 오후 9시 20분이라고 입력한 것과 우리나라에서 4월 30일 오후 9시 20분이라고 입력한것은 전혀 다르다.

그래서 Calendar Property는 UTC로 저장한다. 그런데 사용자의 접속시간 등 다른 시간들의 표현에 문제가 있다. 난 오전 10시에 로그인했는데 오전 1시에 접속한 걸로 나오면 아마 프로그래밍 버그를 의심할 것이다.

이런 날짜의 문제뿐 아니라 이전 국제화 글에서 지적한 바와 같이 숫자의 표현 등에도 난제는 많다. (통화는 PropertyType에 없다는 것이 좀 위안이 된다. -ㅅ-)  이 것을 "시간의 침묵" 이라고 부르기로 했다. -ㅅ-

'Framework > Another Lore' 카테고리의 다른 글

최근에 책을 읽다가..  (0) 2009.06.11
AL : Permission  (1) 2009.04.30
AL : Workspace  (0) 2009.04.28
AL : Property Type Conversion  (0) 2009.04.26
AL : Reading  (0) 2009.04.25
Posted by bleujin
Framework/Another Lore2009. 4. 28. 11:59


A repository may support workspace management. A repository that supports this feature must the semantics of multiple workspaces  and support cross-workspace operations (copying across Workspaces and cloning and updating node, share node)

AL은 Worksapce에서 좀 다른 기능을 가지고 있다.

AL은 1개 이상의 Workspae로 구성되어 있고 AnotherLore.login(new Credential("bleujin"), "otherWorkspaceName") ; 로 통해 default가 아닌 다른 Worksapce에 접속할 수 있다.

이를테면 이런 경우를 생각하면 된다. AL을 이용하여 인사관리 시스템을 만들었다. 이제 재고관리 프로그램을 만들어야 할때 또 다른 AL을 설치해야 할까?


또 다른 AL이 필요치는 않다. 다만 새로운 Workspace를 정의해 두고 재고관리 프로그램은 이 newWorkspace를 사용하면 된다. 

 <global-store> 
  <reference-storage>default-dc</reference-storage>
 </global-store>


 <workspaces>
  <workspace name="default_workspace" default="true">
   <default-locale>ko</default-locale>
   <reference-storage>default-dc</reference-storage>
  </workspace>

  <workspace name="other_workspace">
   <default-locale>en</default-locale>
   <reference-storage>default-dc</reference-storage>
  </workspace>

  <workspace name="other2_workspace">
   <default-locale>en</default-locale>
   <reference-storage>default-mm</reference-storage>
  </workspace>

 </workspaces>
 
 
 <storage id="default-mm" type="memory">
 </storage>

 <storage id="default-dc" type="db.oracle">

 <database-controller>
  <controller-name>framework default database service</controller-name>
  <database-manager>
   <!-- Development server2 ,novision -->

   <description>Oracle database manager.</description>
   <configured-object>
    <class-name>com.bleujin.framework.db.manager.Oracle9iCacheDBManager</class-name>
    <constructor>
     <constructor-param>
      <description>jdbcURL</description>
      <type>java.lang.String</type>
      <value>jdbc:oracle:thin:@novision:1521:bleujin</value>
     </constructor-param>
     <constructor-param>
      <description>userId</description>
      <type>java.lang.String</type>
      <value>al</value>
     </constructor-param>
     <constructor-param>
      <description>password</description>
      <type>java.lang.String</type>
      <value>redf</value>
     </constructor-param>
     <constructor-param>
      <description>connectionLimit</description>
      <type>int</type>
      <value>10</value>
     </constructor-param>
    </constructor>
   </configured-object>
   
  </database-manager>
  <test-query>select 1</test-query>

 </database-controller>
 </storage>
 
위와 같이 설정되 있을 경우 AL은 1개의 GlobalStorage와 3개의 WorkspaceStorage를 가진다.
GlobalStorage는 주로 NodeType과 Sequecne등의 Global 객체 정보를 가지고 있으며 개개의 Workspace는 개별적인 Tree 형태의 Node 구조를 가지고 있다.

특징적인 점은 other_workspace와 other_workspace는 같은 DB를 참조하고 있다. Workspace는 Storage형태가 메모리이든(물론 이경우 매번 리셋된다.) DB이든 상관하지 않으며 다른 DB 종류일수도 있고 같은 DB이지만 Schema만 다를 수 있고 심지어는 같은 DB의 같은 Table에 여러개의 workspace 정보를 관리할 수도 있다.

이런 구조를 택한 이유는 Workspace로 관리하고자 하는 Node의 양이 상황에 따라 다르기 때문이다. 이를테면 A Workspace가 전체 노드의 50%이상이고 나머지 50% 이하를 9개의 Workspace가 관리한다면 A Workspace만 별도의 DB로 관리하고 나머지 9개를 하나의 Storage로 공유하여 사용할 수 있다.

AnotherLore.logn(Credential)로 접속을 하면 default=true인 Default Worksapce로 접속하고 일반적으로는 AnotherLore.login(Credintial, workspaceName)으로 별도의 Session을 할당받는다.

기본적으로는 A workspace로 login해서 얻은 NodeA는
B Workspace의 NodeB를 Node.getIdentifier로 언제든 참조할 수 있지만 각각의 Workspace는 개별적인 SecurityFilter를 관리하기 때문에 특정 ShareNode만 노출시킬 수도 있다.









'Framework > Another Lore' 카테고리의 다른 글

AL : Permission  (1) 2009.04.30
AL : 현재의 난제들  (0) 2009.04.30
AL : Property Type Conversion  (0) 2009.04.26
AL : Reading  (0) 2009.04.25
AL : Link  (0) 2009.04.24
Posted by bleujin
Framework/Another Lore2009. 4. 26. 06:54

When the value of a property is read or written using a type different from that declared for the property, the repository attempts a type conversion according to the following rules. Note that even in cases where the type conversion is
defined in terms of standard JDK type conversion method, failure of conversion must only ever cause a ValueFormatException to be thrown and never any exception defined in the JDK API.



From STRING To

INPUTSTREAM: The string is encoded using UTF-8.
DATE: If the string is in the format(yyyyMMdd hh24miss) From DATE To, it is converted directly,
     otherwise a ValueFormatException is thrown.
DOUBLE: The string is converted using java.lang.Double.valueOf(String).
DECIMAL: The string is converted using the constructor java.math.BigDecimal(String).
LONG: The string is converted using java.lang.Long.valueOf(String).
BOOLEAN: The string is converted using java.lang.Boolean.valueOf(String).
OBJECT : The string(String)


From BINARY To

STRING: return binary.toXML().toString()
OBJECT : return binary (BinaryPropertyValue)
All Others: A ValueFormatException is thrown.



From DATE To

STRING: The date is converted to the following format:
   yyyyMMdd hh24miss(gregorian
INPUTSTREAM: The date is converted to a string, and this string is encoded in UTF-8.
DOUBLE: The date is converted to the number of milliseconds
     since 00:00 (UTC) 1 January 1970 (1970-01-01T00:00:00.000Z).
     If this number is out-of-range for a double, a ValueFormatException is thrown.
DECIMAL: The date is converted to the number of milliseconds
      since 00:00 (UTC) 1 January 1970(1970-01-01T00:00:00.000Z).
LONG: The date is converted to the number of milliseconds
      since 00:00 (UTC) 1 January 1970 (1970-01-01T00:00:00.000Z). 
      If this number is out-of-range for a long, a ValueFormatException is thrown.
OBJECT : The date(Calendar of Gregorian)
All Others: A ValueFormatException is thrown.


From DOUBLE To

STRING: The double is converted using java.lang.Double.toString().
INPUTSTREAM: The double is converted to a string, and this string is encoded in UTF-8.
DECIMAL: The double is converted using the constructor java.math.BigDecimal(double).
DATE: The double is coerced to a long using standard Java type coercion
      and interpreted as the number of milliseconds since 00:00 (UTC) 1 January 1970(1970-01-01T00:00:00.000Z).
      If the resulting value is out of range for a date, a ValueFormatException is thrown.
LONG: Standard Java type coercion is used.
OBJECT : The double (Double)
All Others: A ValueFormatException is thrown.


From DECIMAL To

STRING: The decimal is converted using java.math.BigDecimal.toString().
INPUTSTREAM: The decimal is converted to a string, and this string is encoded in UTF-8.
DOUBLE: The decimal is converted using java.math.BigDecimal.doubleValue().
DATE: The decimal is converted to a long and interpreted as the number of milliseconds
      since 00:00 (UTC) 1 January 1970 (1970-01-01T00:00:00.000Z).
      If the resulting value is out of range for a date, a ValueFormatException is thrown.
LONG: The decimal is converted using java.math.BigDecimal.longValue().
OBJECT : The decimal(BigDecimal)
All Others: A ValueFormatException is thrown.


From LONG To

STRING: The long is converted using java.lang.Long.toString().
INPUTSTREAM: The long is converted to a string, and this string is encoded in UTF-8.
DECIMAL: The double is converted using the method java.math.BigDecimal.valueOf(long).
DATE: The long is interpreted as the number of milliseconds
     since 00:00 (UTC) 1 January 1970 (1970-01-01T00:00:00.000Z).
     If the resulting value is out of range for a date, a ValueFormatException is thrown.
DOUBLE: Standard Java type coercion is used.
OBJECT : The long(Long)
All Others: A ValueFormatException is thrown.


From BOOLEAN To

STRING: The boolean is converted using java.lang.Boolean.toString().
INPUTSTREAM: The boolean is converted to a string, and this string is encoded in UTF-8.
OBJECT : The boolean(Boolean)
All Others: A ValueFormatException is thrown.



From NAME

STRING: The name is converted to qualified name(IDString)
INPUTSTREAM: The name is converted to a string, and then encoded using UTF-8.
OBJECT : The name(IDString)
All Others: A ValueFormatException is thrown.


From PATH

STRING: The name is converted to qualified name(IDString)
INPUTSTREAM: The name is converted to a string, and then encoded using UTF-8.
OBJECT : The node of path(Node)
All Others: A ValueFormatException is thrown.


From REFERENCE

STRING: The reference is converted to string
INPUTSTREAM: The name is converted to a string, and then encoded using UTF-8.
OBJECT : The node of identifier(Node)
All Others: A ValueFormatException is thrown.



From TEXT

STRING: The text is converted to string
INPUTSTREAM: The text is converted to a string, and then encoded using UTF-8.
OBJECT : The text is converted to stringBuffer
All Others: A ValueFormatException is thrown.



From VERTUAL_TEXT

STRING: The text is converted to string
INPUTSTREAM: The text is converted to a string, and then encoded using UTF-8.
OBJECT : The text is converted to translated string(translate template)
All Others: A ValueFormatException is thrown.





'Framework > Another Lore' 카테고리의 다른 글

AL : 현재의 난제들  (0) 2009.04.30
AL : Workspace  (0) 2009.04.28
AL : Reading  (0) 2009.04.25
AL : Link  (0) 2009.04.24
AL : Observation  (0) 2009.04.24
Posted by bleujin