SlideShare ist ein Scribd-Unternehmen logo
1 von 71
Downloaden Sie, um offline zu lesen
Chicago, October 19 - 22, 2010
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Case Study: Migrating
Hyperic from EJB to
Spring! !
Jennifer Hickey
SpringSource
SpringSource Hyperic
Application and Infrastructure Management
• Discover
– Automatically find all resources
• Monitor
– Availability, performance, capacity,
history
• Track
– Logs, configuration, change management
• Alert
– Advanced condition definition, notification
& escalation schemes
• Control
– Proactive, automated actions
• Analyze
– Answer questions, plan for the future
Basic HQ Architecture
machine 1
HQ
Agent
machine n
HQ
Agent
HQ
Server HQ
Web
Portal
Inventory,
Metric,
Audit, …
items
to
manage
items
to
manage
HQ
API
Hyperic’s Server Architecture
Why Migrate?
The Obvious Answer:
5
But there’s a lot more to it....
0% 10% 20% 30% 40% 50% 60% 70%
Java Application Server Usage, Source: 2008 Evans Data Survey
Spring Applications
WebLogic 26%
JBoss 38%
WebSphere 43%
Apache Tomcat 68%
Today’s De Facto Standards
Spring and Tomcat
• Spring: Enterprise Java programming model
– Centralized configuration, declarative transactions, security,
messaging, remoting, Web MVC, Web Flow, persistence
integration, enterprise integration, batch, …
• Tomcat: Lean and powerful Web application server
How Does Lean Help?
• Installation and Provisioning
– 100X Smaller Install Footprint: Less than 50MB vs. multi-Gigabytes
• Hardware, software, lost productivity across Dev, QA, Staging, Production
• Simpler Configuration Improves Debugging and Quality
– Impact of complexity across Dev, QA, Staging, Production adds up
– “60% cite faster project completion and application quality as top reasons for
using Spring”
• Upgrade and Migration
– Lower complexity = faster migration / upgrade
• Developer Productivity
– Fast Server Startup/Shutdown
• One Developer coding/debugging an app (5 mins x 12 per day = 1 hr)
• Fluidity of Personnel
– Simpler systems = faster rampup
• License and Maintenance Costs
– tc Server is 33% to 75% savings vs. competitor annual maintenance;
additional savings when license costs are factored in
Project Timeline
M1 M2
Sept 21 Dec 24
Nov 20 Jan 15 Feb 19 Oct 15
May 28
M3 M4 M5
Planning a Migration
• Build an accurate picture of the candidate app
– Java EE APIs used
– 3rd party libraries
– Packaging
– Types and number of components
– Assess code quality (coupling, etc.)
• Analyze migration complexity
• Decide partial vs full migration
• Resource Estimation
9
Factors in Migration Complexity
Factor Effect on Complexity
Good documentation and clear
understanding of existing code,
database or requirements
Low complexity
Poor documentation and/or lack
of clear understanding of
existing code, database or
requirements
Low to medium complexity
Well architected, layered
application
Low complexity
Organically grown, non-layered
code and architecture, combined
with need to refactor
Low to medium complexity
Factors in Migration Complexity
Factor Effect on Complexity
Organization already familiar
with and using Tomcat/tc Server
and/or lightweight technologies
such as Spring Framework.
Low complexity
Strong organizational support of
legacy EJB and full stack Java
EE technologies; Tomcat/tc
Server and/or lightweight
technologies such as Spring
Framework not yet adopted
Medium complexity
No integration with proprietary
application server frameworks
or APIs
Low complexity
Factors in Migration Complexity
Factor Effect on Complexity
Integration with proprietary
application server
frameworks or APIs
Low to high complexity depending
on extent of usage
No reliance on Session
EJBs, or reliance on a
straightforward use of
Session EJBs (e.g. smaller
quantity or delegating to
plain Java business objects)
server frameworks or APIs
Low to high complexity depending
on extent of usage
Heavy use of Session EJBs Medium complexity
Factors in Migration Complexity
Factor Effect on Complexity
Reliance on stateful middle tier
clustering (EJB Stateful Session
Beans)
Medium complexity
True need for distributed
transactions
Medium to high complexity
Straightforward DAO-based
database access (using either JDBC
or ORM)
Low complexity
Reliance on Entity Beans Medium to high complexity
depending on amount of
code
Factors in Migration Complexity
Factor Effect on Complexity
Servlet-spec Security usage Low complexity
Declarative EJB (Container
Managed) Security usage
Medium complexity
With Spring Security: Low-
Medium
Using existing full stack
application server's built-in JMS
provider
Low to medium complexity
depending on ability to use
external commercial or open
source JMS container.
Generally only licensing (no
code changes) concern.
Project Evolution Complexity Analysis
• 80 Stateless Session Beans
• 0 Stateful Session Beans
• 3 MDBs
• 0 Entity Beans
• All Container-Managed Transactions, No XA
• JBoss Dependencies:
– JAAS
– Mail Service
– Deployment Scanner
– Schedulers
– HA
• SpringSource Migration Tool helps with analysis
15
Partial vs Full Migration
• Project worked in parallel with other releases
• Largest percentage of test coverage in system tests (vs
standalone unit and integration tests) necessitated a
partially migrated app
16
Extras
• Switch from svn to git
• Modularize monolithic codebase
• Add Java 5 constructs
• Add code conventions
• Switch from ant to maven
• Introduce Eclipse Groovy plugin
17
Resources
• Estimated 8 weeks for one person to do initial conversion
from EAR to WAR on Tomcat
• From beginning to functional complete (M5), project was
staffed with 1.5 full-time people.
• Initial conversion was done by 1.5 people in 12 weeks
18
Project Timeline
M1 M2
Sept 21 Dec 24
Nov 20 Jan 15 Feb 19 Oct 15
May 28
M3 M4 M5
M1 Goal
A JBoss-dependent EAR with no more Stateless Session
EJBs (all converted to POJOs and bootstrapped/
transaction-managed by Spring)
20
Preliminary Steps
• Changed ant to compile at Java 5 compliance
• Removed Xdoclet deployment descriptor and interface
generation from build
• Added “Local” interfaces to source control
• Added deployment descriptors to source control
• Added “Util” lookup classes to source control
• Introduced Eclipse projects for compiling UI plugin groovy
code
21
Dependency Injection
22
• Added temporary Bootstrap class for creation of Spring
ClasspathXmlApplicationContext
• Enabled component scanning and autowiring to
instantiate classes marked as @Service, @Repository,
and @Component
• Added @Repository to all DAOs and @Autowired to their
constructors for injection of Hibernate SessionFactory
• Added all EJBs to an app context file with factory-
method=”getOne”
Application Context Files
dao-context.xml
<beans>
<context:annotation-config />
<context:component-scan base-package="org.hyperic,com.hyperic" use-
default-filters="false">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Service"/>
</context:component-scan>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean class="org.springframework.orm.hibernate3.HibernateTemplate">
<constructor-arg ref="sessionFactory"/>
</bean>
</beans>
Application Context Files
ejb-context.xml
<beans default-lazy-init="true">
<bean class="org.hyperic.hq.appdef.server.session.AgentManagerEJBImpl"
factory-method="getOne"/>
... for all EJBs
<tx:jta-transaction-manager />
<tx:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="org.hyperic,com.hyperic">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service"/>
</context:component-scan>
</beans>
Converted EJB Lookup
public class AgentManagerEJBImpl implements SessionBean {
public static AgentManagerLocal getOne() {
try {
return AgentManagerUtil.getLocalHome().create();
} catch (Exception e) {
throw new SystemException(e);
}
}
}
Application Context Instantiation
public class Bootstrap {
private static final String[] APP_CONTEXT_FILES = new String[]
{ "classpath*:/META-INF/spring/dao-context.xml" };
private static final String[] EJB_APP_CONTEXT_FILES = new String[]
{ "classpath*:/META-INF/spring/ejb-*context.xml" };
private static ApplicationContext APP_CONTEXT;
public synchronized static ApplicationContext getContext() throws
Exception {
boolean initialize = false;
if (APP_CONTEXT == null) {
initialize = true;
APP_CONTEXT = new ClassPathXmlApplicationContext
(APP_CONTEXT_FILES, false);
}
if (initialize) {
((ConfigurableApplicationContext) APP_CONTEXT).refresh();
}
return APP_CONTEXT;
}
Application Context Instantiation (2)
public static synchronized void loadEJBApplicationContext() throws
Exception {
APP_CONTEXT = new ClassPathXmlApplicationContext
(EJB_APP_CONTEXT_FILES, APP_CONTEXT);
}
public static <T> T getBean(Class<T> beanClass) throws Exception {
Collection<T> beans = getContext().getBeansOfType(beanClass).values();
... lookup from parent context if not found
return beans.iterator().next();
}
public static Object getBean(String name) throws Exception {
Object bean = getContext().getBean(name);
... lookup from parent context if not found
return bean;
}
Data Access and Transactions with Spring
and EJB
• Added Commons DBCP BasicDataSource
• Added TransactionAwareDataSourceProxy to allow legacy
code making direct use of DataSource to participate in
Spring-managed transactions
• Added a Spring JTATransactionManager and
@Transactional scanning to support transactions for
converted EJBs
28
Hibernate with Spring and EJB
• Moved creation of Hibernate SessionFactory to Spring's
LocalSessionFactoryBean
• Integrated Hibernate Session management with Spring
transaction management
• The following 4 ways of obtaining a Hibernate session will
all go through the same Spring-managed
SessionFactoryUtils to ensure that each thread will share
a single Hibernate session, regardless of which point was
entered first
1. Hibernate Session is opened during a web request
2. Hibernate Session is opened at beginning of a CMT through the
JBossInterceptor
3. Hibernate Session is opened at beginning of Spring-managed transaction
(currently those converted EJBs marked @Transactional)
4. Hibernate Session is opened by call to HQ SessionManager.runInSession
29
Hibernate with Spring and EJB(2)
hibernate.properties
hibernate.current_session_context_class=org.springframework.orm.hibernat
e3.SpringSessionContext
hibernate.transaction.factory_class=org.hibernate.transaction.JTATransaction
Factory
jta.UserTransaction=UserTransaction
• Hibernate Session is opened during a web request
- Spring OpenSessionInViewFilter
• Hibernate Session is opened at beginning of a CMT through
the JBossInterceptor
- Existing interceptor modified to obtain/start Hibernate sessions through
SessionFactory.currentSession()
• Hibernate Session is opened at beginning of Spring-
managed transaction (currently those converted EJBs
marked @Transactional)
- SpringSessionContext
Hibernate with Spring and EJB(3)
Session opened by call to HQ SessionManager
private void runInSessionInternal(final SessionRunner r) throws Exception {
boolean participate = false;
try {
! if (TransactionSynchronizationManager.hasResource(getSessionFactory())) {
! // Do not modify the Session: just set the participate flag.
! participate = true;
! } else {
! Session session = SessionFactoryUtils.getSession(getSessionFactory(), true);
! session.setFlushMode(FlushMode.MANUAL);
! TransactionSynchronizationManager.bindResource(getSessionFactory(), new
SessionHolder(session));
! }
! HibernateTemplate template = getHibernateTemplate();
! template.execute(new HibernateCallback() {...});
! } finally {
! if (!participate) {
! // single session mode
! SessionHolder sessionHolder = (SessionHolder)
TransactionSynchronizationManager.unbindResource(getSessionFactory());
! SessionFactoryUtils.closeSession(sessionHolder.getSession());
! }
EJB Conversion Checklist
Convert Local Interface
Remove "extends javax.ejb.EJBLocalObject" from the
Local interface
- i.e. AgentManagerLocal
1. Rename the Local interface implemented by the EJB by
removing "Local" from the name
- i.e. AgentManagerLocal becomes AgentManager
2. Replace fully-qualified type names with import-based type
names
- especially in the Local interface
3. Delete Util and LocalHome classes
- i.e. AgentManagerUtil and AgentManagerLocalHome
32
EJB Conversion Checklist
Convert Implementation
Rename the EJB (using Eclipse Refactor->Rename to
update dependencies) by removing "EJB" from the name
- i.e. AgentManagerEJBImpl becomes AgentManagerImpl
1. Remove "implements SessionBean" from EJB class
declaration and make class implement its corresponding
Local interface
2. Move initialization logic from ejbCreate() to an init method
annotated with @PostConstruct
33
@PostConstruct
public void initPager() throws Exception {
valuePager = Pager.getPager(VALUE_PROCESSOR);
}
EJB Conversion Checklist
Convert Implementation (2)
4. Remove all ejb* methods (i.e. ejbCreate) and
setSessionContext method
5. Convert getOne() method to the following:
34
public static AgentManager getOne() {
return Bootstrap.getBean(AgentManager.class);
}
6. Mark the converted EJB with @Service
7. Remove the converted EJBʼs entry from ejb-context.xml
EJB Conversion Checklist
Convert Implementation (3)
8. Remove all mention of the EJB from deployment
descriptors in the HQ/dd or HQ-EE/dd directories
9. If the class is marked with * @ejb:transaction
type="REQUIRED" (prior XDoclet markup for generating
CMT), mark the class @Transactional.
- If any methods are marked with a different ejb:transaction
type, (for example, ejb:transaction
type="REQUIRES_NEW), ignore them and document
10.Remove all the XDoclet markup from javadoc
35
EJB Conversion Checklist
Dependency Injection
1. Remove any EJB dependencies and helper classes
obtained through static lookup
Example:
36
public class SomeConvertedEJB {
private void doSomething() {
EscalationManagerLocal escMan =
EscalationManagerEJBImpl.getOne();
escMan.escalate();
}
Becomes:
public class SomeConvertedEJB {
private EscalationManagerLocal escalationManager;
private void doSomething() {
escalationManager.escalate();
}
EJB Conversion Checklist
Dependency Injection(2)
2. Inject DAOs, EJBs and converted EJBs, and helper
classes by auto-wiring the constructor
37
@Service
@Transactional
public class AgentManagerImpl {
private ResourceEdgeDAO resourceEdgeDAO;
private ServerManagerLocal serverManager;
@Autowired
public AgentManagerImpl(ResourceEdgeDAO
resourceEdgeDAO, ServerManagerLocal serverManager) {
this.resourceEdgeDAO = resourceEdgeDAO;
this.serverManager = serverManager;
}
Struts 1.x and Spring
Added Spring ContextLoader plugin to enable Spring
to manage Struts actions as Beans
struts-config.xml
38
<action path="/escalation/ListActiveEscalations"
scope="request"
type="org.springframework.web.struts.DelegatingActionProxy"/>
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
! ! value="/WEB-INF/spring/action-servlet.xml" />
</plug-in>
<bean name="/escalation/ListActiveEscalations"
class="org.hyperic.hq.ui.json.action.escalation.finder.ListActiveEscala
tions" />
action-servlet.xml
Project Timeline
M1 M2
Sept 21 Dec 24
Nov 20 Jan 15 Feb 19 Oct 15
May 28
M3 M4 M5
M2 Goal
Convert the JBoss-dependent HQ EAR into a single
JBoss-dependent WAR
40
Message-Driven EJB Conversion
• Only 3 MDBs listening to a single JMS topic
• Applied conversion checklist to MDBs
• Subscribed newly converted POJOs to JMS topic using
Spring JMS
jms-context.xml
41
<bean id="registeredDispatcher"
class="org.hyperic.hq.bizapp.server.mdb.RegisteredDispatcherImpl"/>
<jms:listener-container destination-type="topic" concurrency="1"
acknowledge="dups-ok" >
<jms:listener destination="topic/eventsTopic"
ref="registeredDispatcher"/>
</jms:listener-container>
JMS Message Broker Conversion
42
• Introduced embedded ActiveMQ broker to replace
JBossMQ
- Easy to configure with Spring
- Often 10x faster than JBossMQ
• Conversion not technically necessary in this project phase,
but took very little time to implement
ActiveMQ Configuration
43
<amq:broker brokerName="localhost">
! <amq:systemUsage>
! ! <amq:systemUsage>
! ! ! <amq:memoryUsage>
! ! ! <amq:memoryUsage limit="${server.jms.maxmemory} mb" />
! ! ! </amq:memoryUsage>
! ! </amq:systemUsage>
! </amq:systemUsage>
</amq:broker>
<amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost?
create=false" />
<bean id="connectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory">
! <property name="connectionFactory" ref="jmsFactory" />
</bean>
JMS Producer Conversion
Modified single Producer to use Spring JMSTemplate for
message publishing
jms-context.xml
44
<bean id="eventsJmsTemplate"
class="org.springframework.jms.core.JmsTemplate">
! ! <property name="connectionFactory" ref="connectionFactory" />
! ! <property name="defaultDestinationName" value="topic/
eventsTopic" />
! <property name="pubSubDomain" value="true" />
</bean>
JMS Producer: Before
45
public void publishMessage(String name, Serializable sObj) {
TopicConnection conn = null;
TopicSession session = null;
if (_ic == null)
_ic = new InitialContext();
if (_factory == null)
_factory = _ic.lookup(CONN_FACTORY_JNDI);
TopicConnectionFactory tFactory = (TopicConnectionFactory) _factory;
Topic topic = getTopic(name);
if (topic != null) {
// Now create a connection to send a message
if (_tConn != null)
conn = _tConn;
else
conn = tFactory.createTopicConnection();
if (conn == null)
_log.error("TopicConnection cannot be created");
if (_tSession != null)
session = _tSession;
else
session = conn.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
// Create a publisher and publish the message
TopicPublisher publisher = session.createPublisher(topic);
ObjectMessage msg = session.createObjectMessage();
msg.setObject(sObj);
publisher.publish(msg);
JMS Producer: After
46
public void publishMessage(String name, Serializable sObj) {
eventsJmsTemplate.convertAndSend(name, sObj);
}
MBean Conversion
47
• EAR contained several JBoss SARs (Service Archive files)
registering MBeans with product functionality
• Most MBeans not actually used for runtime management
and monitoring
• JBoss Scheduler MBeans
- A few classes registered as MBeans just to integrate with
JBoss Schedulers
- Registered JBoss schedulers programmatically
• JBoss Mail Service MBean
- Registered JBoss mail service programmatically
• JBoss Deployment Scanner
- Used for hot deploy of product plugins. Temporarily disabled
JMX with Spring
48
<beans>
<context:mbean-export />
! <context:mbean-server />
Switched to Spring JMX for exposure of actual management
and monitoring interfaces
@ManagedResource("hyperic:type=Service,name=ProductPluginDeployer")
@Service
public class ProductPluginDeployer {
@ManagedMetric
public int getProductPluginCount() {...}
@ManagedAttribute
public ArrayList<String> getRegisteredPlugins(String type) {...}
@ManagedOperation
public void setProperty(String name, String value) {...}
Web Conversion
49
• Added Spring WebApplicationContext
• Kept Bootstrap class for static access to Web App Context
web.xml
<context-param>
! <param-name>contextConfigLocation</param-name>
! <param-value>
! ! classpath*:/META-INF/spring/*-context.xml
! </param-value>
</context-param>
!
<listener>
! <listener-
class>org.hyperic.hq.context.BootstrapContextLoaderListener</listener-
class>
</listener>
• Auto-wired Struts actions with Service dependencies
Transaction Management
50
Switched from JTA TransactionManager to Hibernate
TransactionManager
<beans>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionMana
ger"
! ! p:defaultTimeout="900">
! ! <property name="sessionFactory" ref="sessionFactory" />
! </bean>
Project Timeline
M1 M2
Sept 21 Dec 24
Nov 20 Jan 15 Feb 19 Oct 15
May 28
M3 M4 M5
M3 Goal
Run the basic HQ and HQ EE wars on Tomcat, breaking
all EJB and JBoss dependencies
-Deferring some advanced functionality to a future milestone:
-Unidirectional agent (JBoss Remoting)
-HA
-Kerberos and LDAP authentication
-Plugin hot deploy
52
Security Conversion
Replaced JBoss JAAS for simple JDBC login with Spring
Security 3
53
<bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.Md5Pass
wordEncoder">
! ! <property name="encodeHashAsBase64" value="true" />
</bean>!
! <bean id="internalAuthenticationProvider"
class="org.hyperic.hq.security.InternalAuthenticationProvider"/>
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
! <property name="providers">
!
! <list>
!
! ! <ref local="anonymousAuthenticationProvider" />
! ! <ref local="internalAuthenticationProvider" />
!
! </list>
! </property>
</bean>
Scheduling Conversion
Replaced use of JBoss Scheduler MBeans with Spring
3.0 Scheduler/TaskExecutor abstraction
54
<task:scheduler id="scheduler" pool-size="10"/>
@Service("availabilityCheckService")
public class AvailabilityCheckServiceImpl implements
AvailabilityCheckService {
@Scheduled(fixedRate=120000)
public void backfill() {
...
}
}
The Last of EJB and JBoss....
• Merged JBoss logging config from custom jboss-log4j.xml
to single log4j.xml
• Removed EJB and Remote Exceptions from all method
throws clauses
• Replaced references to JBoss server home directory and
JBoss temp dir for File I/O
55
Final Steps
Deployed the WAR on Tomcat as the ROOT webapp
• When we ported the WAR from JBoss to Tomcat, we only
had to fix 2 small issues before it functioned properly:
- jsp-api.jar was causing conflicts and had to be removed
from WAR
- A few resources (such as images) were being loaded using
getResourceAsStream() from the WebAppClassLoader
(getClass().getClassLoader()). In JBoss, the ClassLoader
could load relative to top-level WAR dir. On Tomcat, the
ClassLoader is relative to WEB-INF/classes.
56
Project Timeline
M1 M2
Sept 21 Dec 24
Nov 20 Jan 15 Feb 19 Oct 15
May 28
M3 M4 M5
M4 Goal
• Fully installable server and agent distros for all supported
OS/DB combos
-Still missing features left un-implemented in M3
58
M4 Tasks
• Removed all static "getOne" accessor methods from EJBs
• Optimized performance by marking some @Transactionals
as "ReadOnly”
• Created installable servers/agents
- User-configurable properties in a single properties file
(aggregating several JBoss config files)
- Spring PropertyPlaceholderConfigurer makes property
injection easy
- Bundled Tomcat (.org) and tc Server (.com) with final distros
- Added custom config of Tomcat and tc Server
- catalina.properties extracts most container configuration to a
single file
- Modified ant-based installer program
• Developed an integration test of a converted EJB as
template for future testing (using a MySQL database)
59
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Demo
Integration Testing with Spring
Project Timeline
M1 M2
Sept 21 Dec 24
Nov 20 Jan 15 Feb 19 Oct 15
May 28
M3 M4 M5
M5 Goals
• Fully functional product achieving parity with previous
release
• Build system converted from Ant to Maven
62
M5 Tasks
63
• Replaced BasicDataSource with the Tomcat DataSource
(high concurrency connection pool)
• Added LazyConnectionDataSourceProxy
• Added hot deploy of plugins using Roo FileWatcher
• Implemented LDAP authentication with Spring LDAP
• Re-enabled JGroups to complete HA use cases
- Had to manually register a few JBoss MBeans as part of the
web app
• Implemented Kerberos AuthenticationProvider
• Re-enabled JBoss Remoting servlet for unidirectional
agent communications
• Converted build system from Ant to Maven (approx 2
weeks of one person’s time)
• Manual merge of changes made in previous product
releases
Project Timeline
M1 M2
Sept 21 Dec 24
Nov 20 Jan 15 Feb 19 Oct 15
May 28
M3 M4 M5
Some Final Tweaks
Data Access Before
65
public int getServicesCount(AuthzSubject subject) {
Statement stmt = null;
ResultSet rs = null;
Integer subjectId = subject.getId();
try {
Connection conn = getDBConn();
String sql = "SELECT COUNT(SVC.ID) FROM TBL_SERVICE";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
if (rs.next()) {
return rs.getInt(1);
}
} catch (SQLException e) {
log.error("Caught SQL Exception finding Services by type: " + e, e);
throw new SystemException(e);
} finally {
DBUtil.closeJDBCObjects(LOG_CTX, null, stmt, rs);
}
return 0;
Some Final Tweaks
Data Access After
66
public int getServicesCount(AuthzSubject subject) {
String sql = "SELECT COUNT(SVC.ID) FROM TBL_SERVICE";
return jdbcTemplate.queryForInt(sql);
}
Some Final Tweaks
Replaced Tapestry with Spring MVC
67
Replaced a small number of Tapestry Components with
Spring MVC @Controller and @RequestMapping
@Controller
public class SearchController extends BaseController {
@RequestMapping(method = RequestMethod.GET, value = "/search")
! public @ResponseBody
! Map<String, List<String>> listSearchResults(
! ! ! @RequestParam(RequestParameterKeys.SEARCH_STRING)
String searchString,
! ! ! HttpSession session) {
...
}
Wrapping It Up
Improved maintainability, testability, and reliability
68
• Reduced code complexity
• Quicker application start time
• Easier to test product in isolation
• 18% and 12% improvement in unit/integration test code
coverage for .org and .com codebases, respectively
• Approx 7% code reduction in .org and .com codebases
• Faster turnaround time for bug fixes
• Easily extensible architecture allows quicker development
of new features
What’s Next?
69
• Finish conversion from Struts to Spring MVC
• Use MVC to provide WS endpoints, eliminating the need
for existing HQApi groovy controllers
• Eliminate remaining static lookup via the Bootstrap class
• Eliminate passing of auth tokens in method signatures
• Finish conversion of direct SQL in service layer to DAOs
using JdbcTemplate
• Improve scalability
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Q&A
Resources
71
• Hyperic 4.5 Beta Release
- Open Source
http://sourceforge.net/projects/hyperic-hq/files/
- Enterprise Edition
http://www.springsource.com/landing/vfabric-hyperic-45-beta
• Hyperic Development Resources
- Cloning source
- Building from source
- Building plugins
- Accessing maven repo
http://support.hyperic.com/display/EVO/Development+Resources
• tc Server Eval Download
http://www.springsource.com/products/tc-server-evaluation

Weitere ähnliche Inhalte

Was ist angesagt?

AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017Amazon Web Services Korea
 
[IMQA] performance consulting
[IMQA] performance consulting[IMQA] performance consulting
[IMQA] performance consultingIMQA
 
컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항
컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항
컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항Opennaru, inc.
 
Go Profiling - John Graham-Cumming
Go Profiling - John Graham-Cumming Go Profiling - John Graham-Cumming
Go Profiling - John Graham-Cumming Cloudflare
 
마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기Jaewoo Ahn
 
Load-testing 101 for Startups with Artillery.io
Load-testing 101 for Startups with Artillery.ioLoad-testing 101 for Startups with Artillery.io
Load-testing 101 for Startups with Artillery.ioHassy Veldstra
 
Java EE Introduction
Java EE IntroductionJava EE Introduction
Java EE Introductionejlp12
 
Micro services Architecture
Micro services ArchitectureMicro services Architecture
Micro services ArchitectureAraf Karsh Hamid
 
우아한 모노리스
우아한 모노리스우아한 모노리스
우아한 모노리스Arawn Park
 
Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017
Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017
Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017Amazon Web Services Korea
 
실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 YoungSu Son
 
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...HostedbyConfluent
 
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다KWON JUNHYEOK
 
Introduction to Kong API Gateway
Introduction to Kong API GatewayIntroduction to Kong API Gateway
Introduction to Kong API GatewayYohann Ciurlik
 
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...문기 박
 
카프카, 산전수전 노하우
카프카, 산전수전 노하우카프카, 산전수전 노하우
카프카, 산전수전 노하우if kakao
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring SecurityDzmitry Naskou
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...Shotaro Suzuki
 

Was ist angesagt? (20)

Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
 
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
 
[IMQA] performance consulting
[IMQA] performance consulting[IMQA] performance consulting
[IMQA] performance consulting
 
컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항
컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항
컨테이너 (PaaS) 환경으로의 애플리케이션 전환 방법과 고려사항
 
Go Profiling - John Graham-Cumming
Go Profiling - John Graham-Cumming Go Profiling - John Graham-Cumming
Go Profiling - John Graham-Cumming
 
마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기
 
Load-testing 101 for Startups with Artillery.io
Load-testing 101 for Startups with Artillery.ioLoad-testing 101 for Startups with Artillery.io
Load-testing 101 for Startups with Artillery.io
 
Java EE Introduction
Java EE IntroductionJava EE Introduction
Java EE Introduction
 
Micro services Architecture
Micro services ArchitectureMicro services Architecture
Micro services Architecture
 
우아한 모노리스
우아한 모노리스우아한 모노리스
우아한 모노리스
 
Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017
Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017
Amazon ECS를 통한 도커 기반 콘테이너 서비스 구축하기 - AWS Summit Seoul 2017
 
실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우 실전 서버 부하테스트 노하우
실전 서버 부하테스트 노하우
 
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
Intelligent, Automatic Restarts for Unhealthy Kafka Consumers on Kubernetes w...
 
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
 
Introduction to Kong API Gateway
Introduction to Kong API GatewayIntroduction to Kong API Gateway
Introduction to Kong API Gateway
 
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
MSA(Service Mesh), MDA(Data Mesh), MIA(Inference Mesh) 기술동향 소개-박문기@메ᄀ...
 
카프카, 산전수전 노하우
카프카, 산전수전 노하우카프카, 산전수전 노하우
카프카, 산전수전 노하우
 
Introduction to Microservices
Introduction to MicroservicesIntroduction to Microservices
Introduction to Microservices
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring Security
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
 

Ähnlich wie Case Study: Migrating Hyperic from EJB to Spring from JBoss to Apache Tomcat

Streaming to a new Jakarta EE / JOTB19
Streaming to a new Jakarta EE / JOTB19Streaming to a new Jakarta EE / JOTB19
Streaming to a new Jakarta EE / JOTB19Markus Eisele
 
Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)CIVEL Benoit
 
Cerberus_Presentation1
Cerberus_Presentation1Cerberus_Presentation1
Cerberus_Presentation1CIVEL Benoit
 
Streaming to a New Jakarta EE
Streaming to a New Jakarta EEStreaming to a New Jakarta EE
Streaming to a New Jakarta EEJ On The Beach
 
Streaming to a new Jakarta EE
Streaming to a new Jakarta EEStreaming to a new Jakarta EE
Streaming to a new Jakarta EEMarkus Eisele
 
Java on Rails SV Code Camp 2014
Java on Rails SV Code Camp 2014Java on Rails SV Code Camp 2014
Java on Rails SV Code Camp 2014Tim Hobson
 
Tools. Techniques. Trouble?
Tools. Techniques. Trouble?Tools. Techniques. Trouble?
Tools. Techniques. Trouble?Testplant
 
Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)
Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)
Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)Sascha Wenninger
 
Agile Secure Cloud Application Development Management
Agile Secure Cloud Application Development ManagementAgile Secure Cloud Application Development Management
Agile Secure Cloud Application Development ManagementAdam Getchell
 
Node.js BFFs: our way to better/micro frontends
Node.js BFFs: our way to better/micro frontendsNode.js BFFs: our way to better/micro frontends
Node.js BFFs: our way to better/micro frontendsEugene Fidelin
 
Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»
Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»
Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»DataArt
 
Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts weili_at_slideshare
 
Intorduction to struts
Intorduction to strutsIntorduction to struts
Intorduction to strutsAnup72
 
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ... The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...Josef Adersberger
 
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...QAware GmbH
 
Getting to Walk with DevOps
Getting to Walk with DevOpsGetting to Walk with DevOps
Getting to Walk with DevOpsEklove Mohan
 

Ähnlich wie Case Study: Migrating Hyperic from EJB to Spring from JBoss to Apache Tomcat (20)

Streaming to a new Jakarta EE / JOTB19
Streaming to a new Jakarta EE / JOTB19Streaming to a new Jakarta EE / JOTB19
Streaming to a new Jakarta EE / JOTB19
 
Shyam pcf
Shyam pcfShyam pcf
Shyam pcf
 
Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)
 
Cerberus_Presentation1
Cerberus_Presentation1Cerberus_Presentation1
Cerberus_Presentation1
 
Streaming to a New Jakarta EE
Streaming to a New Jakarta EEStreaming to a New Jakarta EE
Streaming to a New Jakarta EE
 
Streaming to a new Jakarta EE
Streaming to a new Jakarta EEStreaming to a new Jakarta EE
Streaming to a new Jakarta EE
 
ABHAY_SHUKLA
ABHAY_SHUKLAABHAY_SHUKLA
ABHAY_SHUKLA
 
Java on Rails SV Code Camp 2014
Java on Rails SV Code Camp 2014Java on Rails SV Code Camp 2014
Java on Rails SV Code Camp 2014
 
Tools. Techniques. Trouble?
Tools. Techniques. Trouble?Tools. Techniques. Trouble?
Tools. Techniques. Trouble?
 
KLAKSHMAN
KLAKSHMANKLAKSHMAN
KLAKSHMAN
 
Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)
Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)
Navigating SAP’s Integration Options (Mastering SAP Technologies 2013)
 
Agile Secure Cloud Application Development Management
Agile Secure Cloud Application Development ManagementAgile Secure Cloud Application Development Management
Agile Secure Cloud Application Development Management
 
Resume
ResumeResume
Resume
 
Node.js BFFs: our way to better/micro frontends
Node.js BFFs: our way to better/micro frontendsNode.js BFFs: our way to better/micro frontends
Node.js BFFs: our way to better/micro frontends
 
Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»
Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»
Станислав Сидоренко «DeviceHive Java Server – миграция на Spring Boot»
 
Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts Build Java Web Application Using Apache Struts
Build Java Web Application Using Apache Struts
 
Intorduction to struts
Intorduction to strutsIntorduction to struts
Intorduction to struts
 
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ... The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
 
Getting to Walk with DevOps
Getting to Walk with DevOpsGetting to Walk with DevOps
Getting to Walk with DevOps
 

Kürzlich hochgeladen

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 

Kürzlich hochgeladen (20)

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

Case Study: Migrating Hyperic from EJB to Spring from JBoss to Apache Tomcat

  • 1. Chicago, October 19 - 22, 2010 SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. Case Study: Migrating Hyperic from EJB to Spring! ! Jennifer Hickey SpringSource
  • 2. SpringSource Hyperic Application and Infrastructure Management • Discover – Automatically find all resources • Monitor – Availability, performance, capacity, history • Track – Logs, configuration, change management • Alert – Advanced condition definition, notification & escalation schemes • Control – Proactive, automated actions • Analyze – Answer questions, plan for the future
  • 3. Basic HQ Architecture machine 1 HQ Agent machine n HQ Agent HQ Server HQ Web Portal Inventory, Metric, Audit, … items to manage items to manage HQ API
  • 5. Why Migrate? The Obvious Answer: 5 But there’s a lot more to it....
  • 6. 0% 10% 20% 30% 40% 50% 60% 70% Java Application Server Usage, Source: 2008 Evans Data Survey Spring Applications WebLogic 26% JBoss 38% WebSphere 43% Apache Tomcat 68% Today’s De Facto Standards Spring and Tomcat • Spring: Enterprise Java programming model – Centralized configuration, declarative transactions, security, messaging, remoting, Web MVC, Web Flow, persistence integration, enterprise integration, batch, … • Tomcat: Lean and powerful Web application server
  • 7. How Does Lean Help? • Installation and Provisioning – 100X Smaller Install Footprint: Less than 50MB vs. multi-Gigabytes • Hardware, software, lost productivity across Dev, QA, Staging, Production • Simpler Configuration Improves Debugging and Quality – Impact of complexity across Dev, QA, Staging, Production adds up – “60% cite faster project completion and application quality as top reasons for using Spring” • Upgrade and Migration – Lower complexity = faster migration / upgrade • Developer Productivity – Fast Server Startup/Shutdown • One Developer coding/debugging an app (5 mins x 12 per day = 1 hr) • Fluidity of Personnel – Simpler systems = faster rampup • License and Maintenance Costs – tc Server is 33% to 75% savings vs. competitor annual maintenance; additional savings when license costs are factored in
  • 8. Project Timeline M1 M2 Sept 21 Dec 24 Nov 20 Jan 15 Feb 19 Oct 15 May 28 M3 M4 M5
  • 9. Planning a Migration • Build an accurate picture of the candidate app – Java EE APIs used – 3rd party libraries – Packaging – Types and number of components – Assess code quality (coupling, etc.) • Analyze migration complexity • Decide partial vs full migration • Resource Estimation 9
  • 10. Factors in Migration Complexity Factor Effect on Complexity Good documentation and clear understanding of existing code, database or requirements Low complexity Poor documentation and/or lack of clear understanding of existing code, database or requirements Low to medium complexity Well architected, layered application Low complexity Organically grown, non-layered code and architecture, combined with need to refactor Low to medium complexity
  • 11. Factors in Migration Complexity Factor Effect on Complexity Organization already familiar with and using Tomcat/tc Server and/or lightweight technologies such as Spring Framework. Low complexity Strong organizational support of legacy EJB and full stack Java EE technologies; Tomcat/tc Server and/or lightweight technologies such as Spring Framework not yet adopted Medium complexity No integration with proprietary application server frameworks or APIs Low complexity
  • 12. Factors in Migration Complexity Factor Effect on Complexity Integration with proprietary application server frameworks or APIs Low to high complexity depending on extent of usage No reliance on Session EJBs, or reliance on a straightforward use of Session EJBs (e.g. smaller quantity or delegating to plain Java business objects) server frameworks or APIs Low to high complexity depending on extent of usage Heavy use of Session EJBs Medium complexity
  • 13. Factors in Migration Complexity Factor Effect on Complexity Reliance on stateful middle tier clustering (EJB Stateful Session Beans) Medium complexity True need for distributed transactions Medium to high complexity Straightforward DAO-based database access (using either JDBC or ORM) Low complexity Reliance on Entity Beans Medium to high complexity depending on amount of code
  • 14. Factors in Migration Complexity Factor Effect on Complexity Servlet-spec Security usage Low complexity Declarative EJB (Container Managed) Security usage Medium complexity With Spring Security: Low- Medium Using existing full stack application server's built-in JMS provider Low to medium complexity depending on ability to use external commercial or open source JMS container. Generally only licensing (no code changes) concern.
  • 15. Project Evolution Complexity Analysis • 80 Stateless Session Beans • 0 Stateful Session Beans • 3 MDBs • 0 Entity Beans • All Container-Managed Transactions, No XA • JBoss Dependencies: – JAAS – Mail Service – Deployment Scanner – Schedulers – HA • SpringSource Migration Tool helps with analysis 15
  • 16. Partial vs Full Migration • Project worked in parallel with other releases • Largest percentage of test coverage in system tests (vs standalone unit and integration tests) necessitated a partially migrated app 16
  • 17. Extras • Switch from svn to git • Modularize monolithic codebase • Add Java 5 constructs • Add code conventions • Switch from ant to maven • Introduce Eclipse Groovy plugin 17
  • 18. Resources • Estimated 8 weeks for one person to do initial conversion from EAR to WAR on Tomcat • From beginning to functional complete (M5), project was staffed with 1.5 full-time people. • Initial conversion was done by 1.5 people in 12 weeks 18
  • 19. Project Timeline M1 M2 Sept 21 Dec 24 Nov 20 Jan 15 Feb 19 Oct 15 May 28 M3 M4 M5
  • 20. M1 Goal A JBoss-dependent EAR with no more Stateless Session EJBs (all converted to POJOs and bootstrapped/ transaction-managed by Spring) 20
  • 21. Preliminary Steps • Changed ant to compile at Java 5 compliance • Removed Xdoclet deployment descriptor and interface generation from build • Added “Local” interfaces to source control • Added deployment descriptors to source control • Added “Util” lookup classes to source control • Introduced Eclipse projects for compiling UI plugin groovy code 21
  • 22. Dependency Injection 22 • Added temporary Bootstrap class for creation of Spring ClasspathXmlApplicationContext • Enabled component scanning and autowiring to instantiate classes marked as @Service, @Repository, and @Component • Added @Repository to all DAOs and @Autowired to their constructors for injection of Hibernate SessionFactory • Added all EJBs to an app context file with factory- method=”getOne”
  • 23. Application Context Files dao-context.xml <beans> <context:annotation-config /> <context:component-scan base-package="org.hyperic,com.hyperic" use- default-filters="false"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"/> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> </bean> <bean class="org.springframework.orm.hibernate3.HibernateTemplate"> <constructor-arg ref="sessionFactory"/> </bean> </beans>
  • 24. Application Context Files ejb-context.xml <beans default-lazy-init="true"> <bean class="org.hyperic.hq.appdef.server.session.AgentManagerEJBImpl" factory-method="getOne"/> ... for all EJBs <tx:jta-transaction-manager /> <tx:annotation-driven /> <context:annotation-config /> <context:component-scan base-package="org.hyperic,com.hyperic"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan> </beans>
  • 25. Converted EJB Lookup public class AgentManagerEJBImpl implements SessionBean { public static AgentManagerLocal getOne() { try { return AgentManagerUtil.getLocalHome().create(); } catch (Exception e) { throw new SystemException(e); } } }
  • 26. Application Context Instantiation public class Bootstrap { private static final String[] APP_CONTEXT_FILES = new String[] { "classpath*:/META-INF/spring/dao-context.xml" }; private static final String[] EJB_APP_CONTEXT_FILES = new String[] { "classpath*:/META-INF/spring/ejb-*context.xml" }; private static ApplicationContext APP_CONTEXT; public synchronized static ApplicationContext getContext() throws Exception { boolean initialize = false; if (APP_CONTEXT == null) { initialize = true; APP_CONTEXT = new ClassPathXmlApplicationContext (APP_CONTEXT_FILES, false); } if (initialize) { ((ConfigurableApplicationContext) APP_CONTEXT).refresh(); } return APP_CONTEXT; }
  • 27. Application Context Instantiation (2) public static synchronized void loadEJBApplicationContext() throws Exception { APP_CONTEXT = new ClassPathXmlApplicationContext (EJB_APP_CONTEXT_FILES, APP_CONTEXT); } public static <T> T getBean(Class<T> beanClass) throws Exception { Collection<T> beans = getContext().getBeansOfType(beanClass).values(); ... lookup from parent context if not found return beans.iterator().next(); } public static Object getBean(String name) throws Exception { Object bean = getContext().getBean(name); ... lookup from parent context if not found return bean; }
  • 28. Data Access and Transactions with Spring and EJB • Added Commons DBCP BasicDataSource • Added TransactionAwareDataSourceProxy to allow legacy code making direct use of DataSource to participate in Spring-managed transactions • Added a Spring JTATransactionManager and @Transactional scanning to support transactions for converted EJBs 28
  • 29. Hibernate with Spring and EJB • Moved creation of Hibernate SessionFactory to Spring's LocalSessionFactoryBean • Integrated Hibernate Session management with Spring transaction management • The following 4 ways of obtaining a Hibernate session will all go through the same Spring-managed SessionFactoryUtils to ensure that each thread will share a single Hibernate session, regardless of which point was entered first 1. Hibernate Session is opened during a web request 2. Hibernate Session is opened at beginning of a CMT through the JBossInterceptor 3. Hibernate Session is opened at beginning of Spring-managed transaction (currently those converted EJBs marked @Transactional) 4. Hibernate Session is opened by call to HQ SessionManager.runInSession 29
  • 30. Hibernate with Spring and EJB(2) hibernate.properties hibernate.current_session_context_class=org.springframework.orm.hibernat e3.SpringSessionContext hibernate.transaction.factory_class=org.hibernate.transaction.JTATransaction Factory jta.UserTransaction=UserTransaction • Hibernate Session is opened during a web request - Spring OpenSessionInViewFilter • Hibernate Session is opened at beginning of a CMT through the JBossInterceptor - Existing interceptor modified to obtain/start Hibernate sessions through SessionFactory.currentSession() • Hibernate Session is opened at beginning of Spring- managed transaction (currently those converted EJBs marked @Transactional) - SpringSessionContext
  • 31. Hibernate with Spring and EJB(3) Session opened by call to HQ SessionManager private void runInSessionInternal(final SessionRunner r) throws Exception { boolean participate = false; try { ! if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { ! // Do not modify the Session: just set the participate flag. ! participate = true; ! } else { ! Session session = SessionFactoryUtils.getSession(getSessionFactory(), true); ! session.setFlushMode(FlushMode.MANUAL); ! TransactionSynchronizationManager.bindResource(getSessionFactory(), new SessionHolder(session)); ! } ! HibernateTemplate template = getHibernateTemplate(); ! template.execute(new HibernateCallback() {...}); ! } finally { ! if (!participate) { ! // single session mode ! SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); ! SessionFactoryUtils.closeSession(sessionHolder.getSession()); ! }
  • 32. EJB Conversion Checklist Convert Local Interface Remove "extends javax.ejb.EJBLocalObject" from the Local interface - i.e. AgentManagerLocal 1. Rename the Local interface implemented by the EJB by removing "Local" from the name - i.e. AgentManagerLocal becomes AgentManager 2. Replace fully-qualified type names with import-based type names - especially in the Local interface 3. Delete Util and LocalHome classes - i.e. AgentManagerUtil and AgentManagerLocalHome 32
  • 33. EJB Conversion Checklist Convert Implementation Rename the EJB (using Eclipse Refactor->Rename to update dependencies) by removing "EJB" from the name - i.e. AgentManagerEJBImpl becomes AgentManagerImpl 1. Remove "implements SessionBean" from EJB class declaration and make class implement its corresponding Local interface 2. Move initialization logic from ejbCreate() to an init method annotated with @PostConstruct 33 @PostConstruct public void initPager() throws Exception { valuePager = Pager.getPager(VALUE_PROCESSOR); }
  • 34. EJB Conversion Checklist Convert Implementation (2) 4. Remove all ejb* methods (i.e. ejbCreate) and setSessionContext method 5. Convert getOne() method to the following: 34 public static AgentManager getOne() { return Bootstrap.getBean(AgentManager.class); } 6. Mark the converted EJB with @Service 7. Remove the converted EJBʼs entry from ejb-context.xml
  • 35. EJB Conversion Checklist Convert Implementation (3) 8. Remove all mention of the EJB from deployment descriptors in the HQ/dd or HQ-EE/dd directories 9. If the class is marked with * @ejb:transaction type="REQUIRED" (prior XDoclet markup for generating CMT), mark the class @Transactional. - If any methods are marked with a different ejb:transaction type, (for example, ejb:transaction type="REQUIRES_NEW), ignore them and document 10.Remove all the XDoclet markup from javadoc 35
  • 36. EJB Conversion Checklist Dependency Injection 1. Remove any EJB dependencies and helper classes obtained through static lookup Example: 36 public class SomeConvertedEJB { private void doSomething() { EscalationManagerLocal escMan = EscalationManagerEJBImpl.getOne(); escMan.escalate(); } Becomes: public class SomeConvertedEJB { private EscalationManagerLocal escalationManager; private void doSomething() { escalationManager.escalate(); }
  • 37. EJB Conversion Checklist Dependency Injection(2) 2. Inject DAOs, EJBs and converted EJBs, and helper classes by auto-wiring the constructor 37 @Service @Transactional public class AgentManagerImpl { private ResourceEdgeDAO resourceEdgeDAO; private ServerManagerLocal serverManager; @Autowired public AgentManagerImpl(ResourceEdgeDAO resourceEdgeDAO, ServerManagerLocal serverManager) { this.resourceEdgeDAO = resourceEdgeDAO; this.serverManager = serverManager; }
  • 38. Struts 1.x and Spring Added Spring ContextLoader plugin to enable Spring to manage Struts actions as Beans struts-config.xml 38 <action path="/escalation/ListActiveEscalations" scope="request" type="org.springframework.web.struts.DelegatingActionProxy"/> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" ! ! value="/WEB-INF/spring/action-servlet.xml" /> </plug-in> <bean name="/escalation/ListActiveEscalations" class="org.hyperic.hq.ui.json.action.escalation.finder.ListActiveEscala tions" /> action-servlet.xml
  • 39. Project Timeline M1 M2 Sept 21 Dec 24 Nov 20 Jan 15 Feb 19 Oct 15 May 28 M3 M4 M5
  • 40. M2 Goal Convert the JBoss-dependent HQ EAR into a single JBoss-dependent WAR 40
  • 41. Message-Driven EJB Conversion • Only 3 MDBs listening to a single JMS topic • Applied conversion checklist to MDBs • Subscribed newly converted POJOs to JMS topic using Spring JMS jms-context.xml 41 <bean id="registeredDispatcher" class="org.hyperic.hq.bizapp.server.mdb.RegisteredDispatcherImpl"/> <jms:listener-container destination-type="topic" concurrency="1" acknowledge="dups-ok" > <jms:listener destination="topic/eventsTopic" ref="registeredDispatcher"/> </jms:listener-container>
  • 42. JMS Message Broker Conversion 42 • Introduced embedded ActiveMQ broker to replace JBossMQ - Easy to configure with Spring - Often 10x faster than JBossMQ • Conversion not technically necessary in this project phase, but took very little time to implement
  • 43. ActiveMQ Configuration 43 <amq:broker brokerName="localhost"> ! <amq:systemUsage> ! ! <amq:systemUsage> ! ! ! <amq:memoryUsage> ! ! ! <amq:memoryUsage limit="${server.jms.maxmemory} mb" /> ! ! ! </amq:memoryUsage> ! ! </amq:systemUsage> ! </amq:systemUsage> </amq:broker> <amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost? create=false" /> <bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> ! <property name="connectionFactory" ref="jmsFactory" /> </bean>
  • 44. JMS Producer Conversion Modified single Producer to use Spring JMSTemplate for message publishing jms-context.xml 44 <bean id="eventsJmsTemplate" class="org.springframework.jms.core.JmsTemplate"> ! ! <property name="connectionFactory" ref="connectionFactory" /> ! ! <property name="defaultDestinationName" value="topic/ eventsTopic" /> ! <property name="pubSubDomain" value="true" /> </bean>
  • 45. JMS Producer: Before 45 public void publishMessage(String name, Serializable sObj) { TopicConnection conn = null; TopicSession session = null; if (_ic == null) _ic = new InitialContext(); if (_factory == null) _factory = _ic.lookup(CONN_FACTORY_JNDI); TopicConnectionFactory tFactory = (TopicConnectionFactory) _factory; Topic topic = getTopic(name); if (topic != null) { // Now create a connection to send a message if (_tConn != null) conn = _tConn; else conn = tFactory.createTopicConnection(); if (conn == null) _log.error("TopicConnection cannot be created"); if (_tSession != null) session = _tSession; else session = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); // Create a publisher and publish the message TopicPublisher publisher = session.createPublisher(topic); ObjectMessage msg = session.createObjectMessage(); msg.setObject(sObj); publisher.publish(msg);
  • 46. JMS Producer: After 46 public void publishMessage(String name, Serializable sObj) { eventsJmsTemplate.convertAndSend(name, sObj); }
  • 47. MBean Conversion 47 • EAR contained several JBoss SARs (Service Archive files) registering MBeans with product functionality • Most MBeans not actually used for runtime management and monitoring • JBoss Scheduler MBeans - A few classes registered as MBeans just to integrate with JBoss Schedulers - Registered JBoss schedulers programmatically • JBoss Mail Service MBean - Registered JBoss mail service programmatically • JBoss Deployment Scanner - Used for hot deploy of product plugins. Temporarily disabled
  • 48. JMX with Spring 48 <beans> <context:mbean-export /> ! <context:mbean-server /> Switched to Spring JMX for exposure of actual management and monitoring interfaces @ManagedResource("hyperic:type=Service,name=ProductPluginDeployer") @Service public class ProductPluginDeployer { @ManagedMetric public int getProductPluginCount() {...} @ManagedAttribute public ArrayList<String> getRegisteredPlugins(String type) {...} @ManagedOperation public void setProperty(String name, String value) {...}
  • 49. Web Conversion 49 • Added Spring WebApplicationContext • Kept Bootstrap class for static access to Web App Context web.xml <context-param> ! <param-name>contextConfigLocation</param-name> ! <param-value> ! ! classpath*:/META-INF/spring/*-context.xml ! </param-value> </context-param> ! <listener> ! <listener- class>org.hyperic.hq.context.BootstrapContextLoaderListener</listener- class> </listener> • Auto-wired Struts actions with Service dependencies
  • 50. Transaction Management 50 Switched from JTA TransactionManager to Hibernate TransactionManager <beans> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionMana ger" ! ! p:defaultTimeout="900"> ! ! <property name="sessionFactory" ref="sessionFactory" /> ! </bean>
  • 51. Project Timeline M1 M2 Sept 21 Dec 24 Nov 20 Jan 15 Feb 19 Oct 15 May 28 M3 M4 M5
  • 52. M3 Goal Run the basic HQ and HQ EE wars on Tomcat, breaking all EJB and JBoss dependencies -Deferring some advanced functionality to a future milestone: -Unidirectional agent (JBoss Remoting) -HA -Kerberos and LDAP authentication -Plugin hot deploy 52
  • 53. Security Conversion Replaced JBoss JAAS for simple JDBC login with Spring Security 3 53 <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5Pass wordEncoder"> ! ! <property name="encodeHashAsBase64" value="true" /> </bean>! ! <bean id="internalAuthenticationProvider" class="org.hyperic.hq.security.InternalAuthenticationProvider"/> <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager"> ! <property name="providers"> ! ! <list> ! ! ! <ref local="anonymousAuthenticationProvider" /> ! ! <ref local="internalAuthenticationProvider" /> ! ! </list> ! </property> </bean>
  • 54. Scheduling Conversion Replaced use of JBoss Scheduler MBeans with Spring 3.0 Scheduler/TaskExecutor abstraction 54 <task:scheduler id="scheduler" pool-size="10"/> @Service("availabilityCheckService") public class AvailabilityCheckServiceImpl implements AvailabilityCheckService { @Scheduled(fixedRate=120000) public void backfill() { ... } }
  • 55. The Last of EJB and JBoss.... • Merged JBoss logging config from custom jboss-log4j.xml to single log4j.xml • Removed EJB and Remote Exceptions from all method throws clauses • Replaced references to JBoss server home directory and JBoss temp dir for File I/O 55
  • 56. Final Steps Deployed the WAR on Tomcat as the ROOT webapp • When we ported the WAR from JBoss to Tomcat, we only had to fix 2 small issues before it functioned properly: - jsp-api.jar was causing conflicts and had to be removed from WAR - A few resources (such as images) were being loaded using getResourceAsStream() from the WebAppClassLoader (getClass().getClassLoader()). In JBoss, the ClassLoader could load relative to top-level WAR dir. On Tomcat, the ClassLoader is relative to WEB-INF/classes. 56
  • 57. Project Timeline M1 M2 Sept 21 Dec 24 Nov 20 Jan 15 Feb 19 Oct 15 May 28 M3 M4 M5
  • 58. M4 Goal • Fully installable server and agent distros for all supported OS/DB combos -Still missing features left un-implemented in M3 58
  • 59. M4 Tasks • Removed all static "getOne" accessor methods from EJBs • Optimized performance by marking some @Transactionals as "ReadOnly” • Created installable servers/agents - User-configurable properties in a single properties file (aggregating several JBoss config files) - Spring PropertyPlaceholderConfigurer makes property injection easy - Bundled Tomcat (.org) and tc Server (.com) with final distros - Added custom config of Tomcat and tc Server - catalina.properties extracts most container configuration to a single file - Modified ant-based installer program • Developed an integration test of a converted EJB as template for future testing (using a MySQL database) 59
  • 60. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. Demo Integration Testing with Spring
  • 61. Project Timeline M1 M2 Sept 21 Dec 24 Nov 20 Jan 15 Feb 19 Oct 15 May 28 M3 M4 M5
  • 62. M5 Goals • Fully functional product achieving parity with previous release • Build system converted from Ant to Maven 62
  • 63. M5 Tasks 63 • Replaced BasicDataSource with the Tomcat DataSource (high concurrency connection pool) • Added LazyConnectionDataSourceProxy • Added hot deploy of plugins using Roo FileWatcher • Implemented LDAP authentication with Spring LDAP • Re-enabled JGroups to complete HA use cases - Had to manually register a few JBoss MBeans as part of the web app • Implemented Kerberos AuthenticationProvider • Re-enabled JBoss Remoting servlet for unidirectional agent communications • Converted build system from Ant to Maven (approx 2 weeks of one person’s time) • Manual merge of changes made in previous product releases
  • 64. Project Timeline M1 M2 Sept 21 Dec 24 Nov 20 Jan 15 Feb 19 Oct 15 May 28 M3 M4 M5
  • 65. Some Final Tweaks Data Access Before 65 public int getServicesCount(AuthzSubject subject) { Statement stmt = null; ResultSet rs = null; Integer subjectId = subject.getId(); try { Connection conn = getDBConn(); String sql = "SELECT COUNT(SVC.ID) FROM TBL_SERVICE"; stmt = conn.createStatement(); rs = stmt.executeQuery(sql); if (rs.next()) { return rs.getInt(1); } } catch (SQLException e) { log.error("Caught SQL Exception finding Services by type: " + e, e); throw new SystemException(e); } finally { DBUtil.closeJDBCObjects(LOG_CTX, null, stmt, rs); } return 0;
  • 66. Some Final Tweaks Data Access After 66 public int getServicesCount(AuthzSubject subject) { String sql = "SELECT COUNT(SVC.ID) FROM TBL_SERVICE"; return jdbcTemplate.queryForInt(sql); }
  • 67. Some Final Tweaks Replaced Tapestry with Spring MVC 67 Replaced a small number of Tapestry Components with Spring MVC @Controller and @RequestMapping @Controller public class SearchController extends BaseController { @RequestMapping(method = RequestMethod.GET, value = "/search") ! public @ResponseBody ! Map<String, List<String>> listSearchResults( ! ! ! @RequestParam(RequestParameterKeys.SEARCH_STRING) String searchString, ! ! ! HttpSession session) { ... }
  • 68. Wrapping It Up Improved maintainability, testability, and reliability 68 • Reduced code complexity • Quicker application start time • Easier to test product in isolation • 18% and 12% improvement in unit/integration test code coverage for .org and .com codebases, respectively • Approx 7% code reduction in .org and .com codebases • Faster turnaround time for bug fixes • Easily extensible architecture allows quicker development of new features
  • 69. What’s Next? 69 • Finish conversion from Struts to Spring MVC • Use MVC to provide WS endpoints, eliminating the need for existing HQApi groovy controllers • Eliminate remaining static lookup via the Bootstrap class • Eliminate passing of auth tokens in method signatures • Finish conversion of direct SQL in service layer to DAOs using JdbcTemplate • Improve scalability
  • 70. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. Q&A
  • 71. Resources 71 • Hyperic 4.5 Beta Release - Open Source http://sourceforge.net/projects/hyperic-hq/files/ - Enterprise Edition http://www.springsource.com/landing/vfabric-hyperic-45-beta • Hyperic Development Resources - Cloning source - Building from source - Building plugins - Accessing maven repo http://support.hyperic.com/display/EVO/Development+Resources • tc Server Eval Download http://www.springsource.com/products/tc-server-evaluation