Successfully reported this slideshow.

Jlook open api platform-sysdevguide

841 views

Published on

System development guide for platform

Published in: Technology, Education
  • Be the first to comment

Jlook open api platform-sysdevguide

  1. 1. OPEN API PLATFORMSYSTEM DEVELOPMENTGUIDEMETADATA DRIVENSERVICE PLATFORM HongSeong Jeon jlooktech@gmail.com jlook consulting
  2. 2. APPLICATION LOGICALARCHITECTURE Meta Driven Open API Service Platform Interfaces Services Repositories Security Controller Security Service Security RepositoryOpen API Service Interfaces Metadata Management Generic Controller Generic Service Generic Repository Domain Controller Domain Service Domain Repository Metadata Controller Metadata Service Metadata Repository Infrastructures Security Component Transaction OR Mapping Management Management Management Management Attachment Dynamic View Task & Batch JDBC Pool Management Resolver Scheduler Management
  3. 3. APPLICATION TECHNICALSPECIFICATIONq  Spring framework q  Spring IoC Container q  Spring Web MVC q  Spring Securityq  JBoss – Hibernate, Javassistq  Google h2 Databaseq  Google gsonq  MVEL 2.0q  Apache Velocity Template engineq  Java & Spring framework Annotationq  Qdox
  4. 4. PROJECT STRUCTUREProject Directory Descriptionjlook Project name src/main/java Java sources directory for platform src/test/java Java sources directory for JUnit test src/main/resource Resources directory for platform domain Hibernate mapping configuration directory for domain hibernate Hibernate configuration file jdbc Hibernate jdbc properties file properties Environment properties file spring Spring configuration directory template Hibernate configuration template file velocity Velocity properties file bin Ant build file
  5. 5. JAVA PACKAGESTRUCTUREPackage Structurejlook.framework domain Domain object package account User, group, domain objects annotation jclass, jattr annotation class batch Batch domain objects common Common service domain objects – menu, announcement docs Value object for API documentation metadata Metadata domain objects – JClass, JAttribute, JType management Management domain objects - JAccessLog model UI value object for client application security Security domain objects – JRole, JDataAccessRule, JMenuAccessRule util Utility domain object – JArray, JAttachment widget UI widget domain objects – JWidgetDefinition, JWidgetInstance infrastructure Infrastructure components package for application annotation Annotation – GsonExclude, Message batch Batch task class context Thread context for user information gson Google gson utility
  6. 6. JAVA PACKAGESTRUCTUREPackage Structurejlook.framework infrastructure hibernate Hibernate utility class http http client component jdbc Jdbc base class for repository component junit Junit utility class loader Metadata loading classes security Security classes - JUserEntity tools Generator classes – Hibernate config, API Documentation task Multi threaded tasking classes util Utility classes web Web servlet and filter classes interfaces Interfaces package account Account interfaces – domain, user, group common Common service interfaces – menu, announcement metadata Metadata interfaces – JClass, JAttribute, JType security Security interfaces – role, access rules utility Utility interfaces – array, attachment
  7. 7. JAVA PACKAGESTRUCTUREPackage Structurejlook.framework repository Repository interface package impl Repository implementation class package service Service interface package action JClass Action classes impl Service implementation class package util Service utility classes
  8. 8. SYSTEM DOMAIN OBJECT§  Table에 Entity value object를 정의한 것으로 모든 Domain object는 JObject로 부터 상속을 받 아 정의된다.§  Member variables for JObject domain class §  objectId : 한 Table내에서 entity를 식별하는 Id §  classId : Table를 식별하는 Id §  domainId : Domain을 식별하는 Id §  createdBy : Enttiy를 등록한 JUser objectId §  createdOn : Entity를 등록한 일시 §  updatedBy : Entity를 변경한 JUser objectId §  updatedOn : Entity를 변경한 일시§  Domain annotation : system domain object들의 metadata 를 등록하기 위해 domain object 의 metadata를 annotation으로 정의한다. §  jclass : system domain object에 대한 JClass metadata 정보를 정의하는 annotation §  jattr : system domain object의 Member Variable에 대한 JAttribute metadata 정보를 정의하 는 annotation
  9. 9. SYSTEM DOMAIN OBJECT@jclass(cid=JMetaKeys.JOBJECT, did=JDomainDef.SYSTEM_ID, name=JObject.NAME, type=JClassType.INTERFACE_TYPE, status=JMetaStatus.NONE_TYPE)public class JObject implements Serializable, Comparable<JObject> { public static final String NAME = "JObject”; public static final String A_OID = "objectId"; public static final String A_CID = "classId"; public static final String A_DID = "domainId"; public static final String A_CREATED_BY = "createdBy"; public static final String A_CREATED_ON = "createdOn"; public static final String A_UPDATED_BY = "updatedBy"; public static final String A_UPDATED_ON = "updatedOn"; @jattr(name=A_OID, label="Object Id", type=JPrimitive.LONG_TYPE, length=15, description="Object Id", required=true, unique=true, searchable=true, derived=true) protected Long objectId; @jattr(name=A_CID, label="Class Id", type=JPrimitive.LONG_TYPE, length=15, description="Class Id", required=true, unique=false, searchable=true, derived=true) protected Long classId; @jattr(name=A_DID, label="Domain Id", type=JPrimitive.LONG_TYPE, length=15, description="Domain Id", required=true, primary=true, unique=false, searchable=true, derived=true) protected Long domainId; @jattr(name=A_CREATED_BY, label="CreatedBy", type=JPrimitive.LONG_TYPE, length=15, description="CreatedBy", required=true, unique=false, searchable=true, derived=true) protected Long createdBy; @jattr(name=A_CREATED_ON, label="CreatedOn", type=JPrimitive.TIMESTAMP_TYPE, description="CreatedOn", required=true, unique=false, searchable=true, derived=true) protected Timestamp createdOn; @jattr(name=A_UPDATED_BY, label="UpdatedBy", type=JPrimitive.LONG_TYPE, length=15, description="UpdatedBy", required=false, unique=false, searchable=true, derived=true) protected Long updatedBy; @jattr(name=A_UPDATED_ON, label="UpdatedOn", type=JPrimitive.TIMESTAMP_TYPE, description="UpdatedOn", required=false, unique=false, searchable=true, derived=true) protected Timestamp updatedOn;
  10. 10. HIBERNATE DOMAINCONFIGURATION§  Hibernate domain configuration에는 Database Table과 Domain object간의 mapping 정보 를 정의한다.§  System domain object에 대한 Hibernate domain configuration파일은 resource/framework/ domain Directory 밑에 정의한다.<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping SYSTEM "classpath://hibernate-mapping-3.0.dtd"><hibernate-mapping package="jlook.framework.domain.metadata"> <class name="JClass" table="JCLASS"> <id name="objectId" column="OBJECTID"> <generator class="native"/> </id> <property name="classId" type="long" column="CLASSID" insert="true"/> <property name="domainId" type="long" column="DOMAINID"/> <property name="name" type="string” column="NAME” length="4000” not-null="true"/> <property name="label" type="string" column="LABEL” length="4000”/> <property name="description” type="string" column="DESCRIPTION" length="4000”/> <property name="category" type="string" column="CATEGORY” length="4000”/> <property name="type" type="string" column="TYPE” length="4000”/> <many-to-one name="inheritanceJClass” class="Jclass” column="INHERITANCEJCLASS” lazy="false"/> <property name="inheritanceType” type="string” column="INHERITANCETYPE” length="4000”/> <property name="actionClass" type="string" column="ACTIONCLASS” length="4000”/> <property name="summaryFilter" type="string" column="SUMMARYFILTER” length="4000”/> <property name="JObjectRule" type="string" column="JOBJECTRULE” length="4000”/> <property name="accessRule" type="string" column="ACCESSRULE" length="9" />
  11. 11. HIBERNATE DOMAIN CONFIGURATION <property name="status" type="string" column="STATUS” length="4000”/> <property name="createdBy" type="long" column="CREATEDBY” insert="true"/> <property name="createdOn" type="timestamp” column="CREATEDON” insert="true"/> <property name="updatedBy" type="long" column="UPDATEDBY” update="true"/> <property name="updatedOn" type="timestamp” column="UPDATEDON" update="true"/> <map name="JAttributes" lazy="false" cascade="none" inverse="true"> <key column="JCLASS"/> <map-key column="NAME" type="string"/> <one-to-many class="JAttribute"/> </map> </class> </hibernate-mapping>resource/spring/context-persistence.xml
  12. 12. REPOSITORY LAYER§  Database에 Access하기 위한 Repository Component를 HibernateRepository로부터 상속을 받아 정의한다. package jlook.framework.repository.impl; @Repository(JGenericRepository.ID) public class JGenericRepositoryImpl extends HibernateRepository implements JGenericRepository { private static Log logger = Log.getLog(JGenericRepositoryImpl.class); @Override public Map<String, Object> selectSummaryData(String entityName, String filter, PageUtil page, Map<String,String[]> attrMap,List<String> parentAttrList, JObject parentJObject) throws JRepositoryException { Session session = this.template.getSessionFactory().getCurrentSession();§  Hibernate Template을 이용하여 Database에 Access하는 Logic을 구현한다. HibernateRepository HibernateTemplate setSessionFactory(SessionFactory sessionFactory) setJContextFactory(JContextFactory jContextFactory) JGenericRepository getDomainId() isAdministrator() JContextFactory JGenericRepositoryImpl
  13. 13. SERVICE LAYER§  Service Component는 Repository를 이용해서 Business Logic을 구현하고, Transaction 처 리를 한다. package jlook.framework.service.impl; @Transactional(readOnly = true, rollbackForClassName={GlobalKeys.SERVICE_EXCEPTION, "org.hibernate.exception.ConstraintViolationException", "org.springframework.dao.DataIntegrityViolationException"}) @Service(JGenericService.ID) public class JGenericServiceImpl implements JGenericService { @Override @PreAuthorize("hasPermission(#jObject, create)") @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public JResultModel create(JObject jObject) throws JServiceException { JUserEntity entity = security.getUserEntity(); if(jObject.getClassId()==null) { throw new JServiceException("classId is not setted. - "+jObject); }
  14. 14. SECURITY SERVICE§  로그인한 사용자 정보를 얻고, domainId 및 client type 정보를 얻는 API를 제공한다. package jlook.framework.service.impl; @Transactional(readOnly = true, rollbackForClassName={GlobalKeys.SERVICE_EXCEPTION}) @Service(JSecurityService.ID) public class JSecurityServiceImpl implements JSecurityService, UserDetailsService { package jlook.framework.service.impl; @Transactional(readOnly = true, rollbackForClassName={GlobalKeys.SERVICE_EXCEPTION, "org.hibernate.exception.ConstraintViolationException", "org.springframework.dao.DataIntegrityViolationException"}) @Service(JGenericService.ID) public class JGenericServiceImpl implements JGenericService { @Resource(name=JSecurityService.ID) private JSecurityService security; @Override @PreAuthorize("hasPermission(#classId, {read})") public JSummaryModel getSummaryData(JViewType jViewType, Long classId, PageUtil page, Map<String, String[]> paramMap) throws JServiceException { JUserEntity entity = security.getUserEntity();
  15. 15. INTERFACE LAYER§  Client의 Request를 받아 Business Service를 실행하고 spring ModelAndView 객체를 생성하 여 반환하는 Logic을 정의한다. @RequestMapping(value = "/generic/references", method = RequestMethod.GET) public ModelAndView getReferences( @RequestHeader(value=JHeader.JCONTENT_TYPE, required=false) String contentType, @RequestParam(value=ParamKeys.CLASS_ID, required=true) Long classId) throws JControllerException { Map<Long, String> map; try { map = this.jClassService.getReferences(classId); } catch (JServiceException e) { throw new JControllerException("Fail to get references for JClass. - "+classId,e); } JContentType jContentType = JContentType.getJContentType(contentType); ModelAndView mview = jContentType.create("generic/references"); mview.addObject(JResultModel.DATA_KEY, map); return mview; }
  16. 16. METADATA LOADER§  Platform이 실행되기 위해 System Metadata를 초기에 Loading해야 하는 Component §  Package : jlook.framework.infrastructure.loader §  EnumLoader : System Metadata에서 사용하는 Enumeration Validation을 Loading함. §  MetataLoader : Domain Object에 정의한 Annotation을 Metadata Table에 Loading함. §  InitDataLoader : metadata package에 System Application을 구성하기 위한 Metadata를 정 의한 Enum으로 부터 Metadata를 Loading함. §  ViewLoader : Loading된 JClass Metadata로 부터 각 JClass의 System default JView를 생 성함.§  Metadata Reloading API – MainController : /metadata/load @RequestMapping(value = "/metadata/load", method = RequestMethod.GET) public String loadMetadata(HttpServletRequest request, HttpServletResponse response) throws JControllerException { JSessionFactoryBean bean = (JSessionFactoryBean)ApplicationContextHolder.getBean("&mySessionFactory"); bean.dropDatabaseSchema(); bean.createDatabaseSchema(); ry { this.enumLoader.setDataLoadEnabled(true); this.enumLoader.doInit(); this.metadataLoader.setDataLoadEnabled(true); this.metadataLoader.doInit(); this.dataLoader.setDataLoadEnabled(true); this.dataLoader.doInit();
  17. 17. METADATA LOADER this.viewLoader.setDataLoadEnabled(true); this.viewLoader.doInit(); return "redirect:/"; } catch(Exception e) { throw new JControllerException("Cannot load metadata. - "+e.getMessage(), e); } }§  Source Review §  EnumLoader.java §  InitDataLoader.java §  MetadataLoader.java §  JMenuDef.java
  18. 18. GSON COMPONENT§  JSon Response message를 생성하는 Google gson API를 Wrapper한 Class로 Response Message를 customization하는 Logic을 정의할 수 있다. è jlook.framework.infrastructure.gson.GsonFactory§  JSon Mview에서 Response Value object를 JSon Message로 convert하기 위해 사용한다. Object obj = model.get(JResultModel.DATA_KEY); JResultModel rmodel = null; if(obj instanceof JResultModel) { rmodel = (JResultModel)obj; } else { rmodel = new JResultModel(); rmodel.setData(obj); } Object config = model.get(JResultModel.CONFIG_KEY); if(config instanceof Map) { rmodel.addConfig((Map<String,Object>)config); } if(rmodel.getResult()==null) { rmodel.setResult(JResultModel.SUCCESS); } GsonFactory gsonFactory = (GsonFactory)ApplicationContextHolder.getBean(GsonFactory.ID); Gson gson = gsonFactory.create(); String jsonResult = gson.toJson(rmodel);
  19. 19. DYNAMIC VIEWRENDERING§  JViewResolver : spring View Resolver로 jlook-servlet.xml에 configuration되어 있으며, Response View Name에 따라서 해당 View객체를 생성하여 Response Message를 만들어 Response한다. <bean id="jViewResolver" class="jlook.framework.infrastructure.web.view.JViewResolver"> <property name="jaxbModelList" ref="jaxbModelList"/> </bean> @Override public View resolveViewName(String viewName, Locale locale) throws Exception { if(logger.isDebugEnabled()) { logger.debug("--> resolveViewName - "+viewName); } View view = null; if(JSonView.VIEWNAME.equals(viewName)) { view = new JSonView(); } else if(JXmlView.VIEWNAME.equals(viewName)) { view = new JXmlView(this.jaxbModelList); } else if(JFileView.VIEWNAME.equals(viewName)) { view = new JFileView(); } else if(JExcelView.VIEWNAME.equals(viewName)) { view = new JExcelView(); } return view; }
  20. 20. DYNAMIC VIEWRENDERING§  jlook.framework.infrastructure.web.view package에 Custom View 정의됨 §  JSonView §  JExcelView §  JFileView §  JXmlView§  Client 요청 시 Header에 setting한 “jlook.content.type”에 따라서 Response Message Type 이 결정된다. @RequestMapping(value = "/admin/environment", method = RequestMethod.GET) public ModelAndView envProperties( @RequestHeader(value=JHeader.JCONTENT_TYPE, required=false) String contentType, @RequestParam(value="name", required=false) String name, @RequestParam(value="value", required=false) String value) throws JControllerException { if(name!=null && value!=null) { environment.setProperty(name,value); } JContentType jContentType = JContentType.getJContentType(contentType); ModelAndView mview = jContentType.create("admin/environment"); mview.addObject(JResultModel.DATA_KEY, environment); return mview; }
  21. 21. SERVLET FILTER§  jlook.framework.infrastructure.web.filter package에 두 가지 종류의 System Servlet Filter를 제공함. §  JGlobelFilter : 모든 Request에 대한 Servlet Filter로 로그인한 사용자 정보를 Thread Context Variable에 Setting 하고, Access Log를 남긴다. §  JServiceFilter : /service/*에 대한 요청에 대한 Servlet Filter
  22. 22. SPRING SECURITY§  Spring security framework은 web.xml에 아래와 같이 정의된 Filter에 의해 모든 Request에 대 한 Web Resource의 권한 체크가 처리된다. <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>§  Spring security configuration file은 resource/spring/context-security.xml 이다.§  Service Layer business method에서 아래와 같이 Authorization을 Annotation으로 정의할 수 있다. @Override @PreAuthorize("hasPermission(#classId, {read})") public JSummaryModel getSummaryData( JViewType jViewType, Long classId, PageUtil page, Map<String, String[]> paramMap) throws JServiceException {
  23. 23. SPRING SECURITY§  resource/spring/context-security.xml <global-method-security pre-post-annotations="enabled"> <expression-handler ref="expressionHandler"/> </global-method-security> <http use-expressions="true"> <intercept-url pattern="/service/metadata/load" access="permitAll" /> <intercept-url pattern="/service/testing/**" access="permitAll" /> <intercept-url pattern="/console/**” access="permitAll" /> <intercept-url pattern="/docs/**" access="permitAll" /> <intercept-url pattern="/apidocs/**" access="permitAll" /> <intercept-url pattern="/service/mobile/download" access="permitAll" /> <intercept-url pattern="/service/file/upload" access="permitAll" /> <intercept-url pattern="/service/security/signInFrm" access="permitAll" /> <intercept-url pattern="/service/security/signIn" access="permitAll" /> <intercept-url pattern="/service/security/register" access="permitAll" /> <intercept-url pattern="/service/security/registration" access="permitAll" /> <intercept-url pattern="/service/domain/register" access="permitAll" /> <intercept-url pattern="/service/domain/registration" access="permitAll" /> <intercept-url pattern="/admin/**" access="hasRole(Administrator)" /> <intercept-url pattern="/service/**" access="hasRole(Administrator) or hasRole(User)" /> <form-login login-page="/service/security/signInFrm" authentication-success-handler-ref="authenticationSuccessHandler" authentication-failure-handler-ref="authenticationFailureHandler"/> <logout success-handler-ref="logoutSuccessHandler" invalidate-session="true"/>
  24. 24. SPRING SECURITY§  resource/spring/context-security.xml <session-management> <concurrency-control max-sessions="100" error-if-maximum-exceeded="true" /> </session-management> </http> <authentication-manager> <authentication-provider ref="daoAuthenticationProvider"/> jlook.framework.infrastructure.secu </authentication-manager> rity.spring. JPermissionEvaluator <beans:bean id="expressionHandler" class= "org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> <beans:property name="permissionEvaluator" ref="jPermissionEvaluator"/> </beans:bean> <beans:bean id="anonymousAuthFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter"> <beans:property name="key" value="foobar"/> <beans:property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/> </beans:bean> <beans:bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider"> <beans:property name="key" value="foobar"/> </beans:bean>
  25. 25. SPRING SECURITY§  resource/spring/context-security.xml <beans:bean id="daoAuthenticationProvider class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> <beans:property name="userDetailsService" ref="jSecurityService"/> <beans:property name="passwordEncoder" ref="passwordEncoder"/> </beans:bean> <beans:bean id="logoutSuccessHandler class="jlook.framework.infrastructure.security.spring.SignOutSuccessHandler"> <beans:property name="defaultTargetUrl" value="/service/security/signOut"/> <beans:property name="alwaysUseDefaultTargetUrl" value="true"/> </beans:bean> <beans:bean id="passwordEncoder” class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" > <beans:constructor-arg value="256"/> </beans:bean> <beans:bean id="authenticationSuccessHandler" class="jlook.framework.infrastructure.security.spring.AuthenticationSuccessHandler" > <beans:property name="defaultTargetUrl” value="/service/security/signIn"/> <beans:property name="alwaysUseDefaultTargetUrl" value="true"/> </beans:bean> <beans:bean id="authenticationFailureHandler" class="jlook.framework.infrastructure.security.spring.AuthenticationFailureHandler" > <beans:property name="useForward” value="true"/> <beans:property name="defaultFailureUrl” value="/service/security/signInFrm?singIn_error=true"/> </beans:bean>
  26. 26. OPEN API GENERATOR
  27. 27. HIBERNATE GENERATOR
  28. 28. JAVA CLASS GENERATOR
  29. 29. JGENERIC SERVICE
  30. 30. JCLASSLOADER§  Application Home directory 밑에 classes 디렉토리에 있는 domain class들을 loading하는 ClassLoader로 Web Application ClassLoader를 parent ClassLoader로 갖는다. CLASSPATH 경로의 Class System 들을 Loading하는 JVM ClassLoader ClassLoader Web Application Class들을 WebApplication Loading하는 WAS ClassLoader ClassLoader Custom Domain Class들을 Loading하는 Application JClassLoader ClassLoader
  31. 31. ENTITY META MANAGEMENT AbstractSession FactoryBean JConfigLoader Config.xml Hibernate Session JSpringSession Repository Factory FactoryBean JClassLoader Domain class Configuration Hibernate JavaClassJGenericRepository JGenericRepository Generator Generator 1.  Create domain class 2.  Create hibernate config JMetaService 3.  Add config to hibernate Configuration 4.  Build new SessionFactory by hibernate Configuration 5.  Create JView
  32. 32. ENTITY LIFECYCLE Mapping entity NONE Change entity Unmapping entity Remapping entity Mapping MAPERROR entity Build Metadata Unmapping entity CREATED UNMAPED Change entity Remapping entity Build Metadata CHANGED REMAPED BUILDERROR
  33. 33. ENTITY MAP ACTIONq  Mapping entity q  Make java class from metadata q  Make hibernate config from metadataq  Change entity q  Add and remove attribute q  Change attribute : name, type, primary, unique, virtual q  Cannot change : name and category for JClass (CREATED)q  Unmapping entity q  Change status from CREATED to UNMAPPEDq  Remapping entity q  Change status from UNMAP to REMAPPEDq  Build metadata q  Make java class from metadata for all entities. q  Make hibernate config from metadata for all entities. q  Create and initialize JClassLoader q  Create and initialize JSpringSessionFactoryBean
  34. 34. METADATA CHANGEHISTORYq  Change history for JClass and Jattributeq  JClass q  Name, Category q  InheritanceClass, InheritanceTypeq  JAttribute q  JClass, Name, Type q  Primary, Unique, Virtual

×