おっぴろげjavaee devops

Post on 08-Sep-2014

8.591 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

http://www.flickr.com/photos/jox1989/5327951306

おっぴろげ JavaEE DevOps

おっぴろげ is 何

でもJavaEEの導入事例って あんま聞かなくない?

http://www.flickr.com/photos/dogwelder/94393980

せっかく作ったんだし シガラミがないうちに 全部話してしまえー

http://www.flickr.com/photos/pmillera4/8914149268

永瀬 泰一郎 グリー株式会社

@nagaseyasuhito

http://builder.japan.zdnet.com/sp_oracle/weblogic_2013/35040464/

meets

Scalaでやろうぜ!

やっぱ別チーム行くわ!ノシ

JavaEEやるチャンスや!

ひとりDevOps

http://www.flickr.com/photos/nanophoto69/5294068212

開発 テスト

リリース&デプロイ 運用

椿http://bit.ly/jjug-camellia

開発するぞ

Overviewhttp://www.flickr.com/photos/codlibrary/2282696252

EJB Timer

JMSCDI

JAX-RS

JPA

Abstract Entity

@MappedSuperclass@Setter @Getter@EqualsAndHashCode(of = { "id" })public abstract class BaseEntity { @Id @GeneratedValue(strategy = IDENTITY) private Long id;! @Column(nullable = false) @Version @XmlTransient private Long version;! @Column(nullable = false) @Temporal(TemporalType.TIMESTAMP) @XmlJavaTypeAdapter(ISO8601DateAdapter.class) private Date createdAt;}

LombokJPA JAXB

Xml Adapter

public class ISO8601DateAdapter extends XmlAdapter<String, Date> {! @Override public Date unmarshal(String v) throws Exception { return new Date(ISODateTimeFormat. dateTimeNoMillis().withZoneUTC().parseMillis(v)); }! @Override public String marshal(Date v) throws Exception { return ISODateTimeFormat. dateTimeNoMillis().withZoneUTC().print(v.getTime()); }}

LombokJPA JAXB

Concrete Entity

@Entity@Setter @Getterpublic class User extends BaseEntity { @Column(nullable = false, unique = true) @Pattern(regexp = "[\\p{Alnum}]*") private String name;! @Column(nullable = false) @XmlTransient private String password;}

Bean ValidationLombokJPA JAXB

Abstract Dao

public interface Query<T> { CriteriaQuery<T> execute( CriteriaBuilder b, CriteriaQuery<T> q, Root<T> r);}

JPA

Abstract Dao

public abstract class BaseDao<T> { protected T getSingleResult(Query<T> query) { CriteriaBuilder b = this.entityManager.getCriteriaBuilder();! CriteriaQuery<T> q = b.createQuery(this.getEntityClass());! Root<T> r = q.from(this.getEntityClass());! return this.entityManager.createQuery( query.execute(b, q, r)).getSingleResult(); }! protected abstract Class<T> getEntityClass();}

JPA

Concrete Dao

public class UserDao extends BaseDao<User> {! public User findByName(final String name) { return this.getSingleResult(new Query<User>() { @Override public CriteriaQuery<User> execute( CriteriaBuilder b, CriteriaQuery<User> q, Root<User> r) {! return q.select(r). where(b.equal(r.get(User_.name), name)); } }); }}

JPA

Concrete Dao

public class UserDao extends BaseDao<User> {! public User findByName(String name) { return this.getSingleResult((b, q, r) -> q.select(r).where(b.equal(r.get(User_.name), name)); }}

Service

@Transactionalpublic class UserService { @Inject private UserDao userDao;! public User create(@NotNull String name) { User user = new User(name); this.userDao.persist(user);! return user; }! public User show(@NotNull String name) { return this.userDao.findByName(name); }}

Bean ValidationCDI

JAX-RS

@Path("user")public class UserResource { @Inject private UserService userService;! @Path("{name}") // PUT /user/{name} @PUT public User create(@PathParam("name") String name) { return this.userService.create(name); }! @Path(“{name}") // GET /user/{name} @GET public User show(@PathParam("name") String name) { return this.userService.show(name); }}

CDIJAX-RS

テストするぞ

http://www.flickr.com/photos/mattt_org/2831690932

Separate UT and IT

どう分けるか

Integration Test

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <executions> <execution> <goals> <goal>integration-test</goal> </goals> </execution> </executions></plugin>

Integration Test

mvn verify

Unit Test

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/*IT.java</exclude> </excludes> </configuration></plugin>

Unit Test

mvn test

Preparing Entity

Manager

<persistence> <persistence-unit name="camellia" transaction-type="JTA">! <jta-data-source>jdbc/camellia</jta-data-source>! <exclude-unlisted-classes> false </exclude-unlisted-classes>! <properties> <property name="eclipselink.ddl-generation" value="create-tables" /> </properties>! </persistence-unit></persistence>

Preparing Entity

Manager

Map<String, String> prop = Maps.newHashMap();!prop.put("javax.persistence.transactionType", "RESOURCE_LOCAL");prop.put("javax.persistence.jtaDataSource", "");prop.put("javax.persistence.jdbc.driver", "org.h2.Driver");prop.put("javax.persistence.jdbc.url", "jdbc:h2:mem:");!EntityManagerFactory entityManagerFactory = Persistence. createEntityManagerFactory("camellia", prop);!EntityManager entityManager = entityManagerFactory.createEntityManager();

JPA

Concrete Dao Test

public class UserDaoTest extends BaseDaoTest { private FixtureHelper fixtureHelper = new FixtureHelper();! private UserDao userDao = new UserDao();! @Before public void before() throws Throwable { Deencapsulation.setField(this.fixtureHelper, this.getEntityManager());! Deencapsulation.setField(this.userDao, this.getEntityManager()); }

JUnit JMockit

Concrete Dao Test

@Test public void findByNameSuccess() { this.fixtureHelper. createUser("user", "password");! assertThat( this.userDao.findByName("user”).getName(), is("user")); }}

JUnit

Abstract Integration

Test

@RunWith(Arquillian.class)public abstract class BaseServiceIT {! @Deployment public static Archive<?> createDeployment() { WebArchive war = ShrinkWrap.create(WebArchive.class);! war.addPackages(true, Root.class.getPackage()); war.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); war.addAsResource("META-INF/persistence.xml");! return war; }}

ArquillianJUnit

Concrete Integration

Test

public class UserServiceIT extends BaseServiceIT { @Inject private FixtureHelper fixtureHelper; @Inject private UserService userService;! @Test public void createSuccess() { assertThat( this.userService.create("create user", "password"), is(notNullValue())); }! @Test(expected = TransactionalException.class) public void createFailureByDuplicatedName() { this.userService.create("duplicated user","password"); this.userService.create("duplicated user","password"); }}

CDIJUnit

リリース&デプロイするぞ

http://www.flickr.com/photos/ivyfield/4763965911

Release and

Versionリリースとバージョン

maven release plugin

<scm> <url>https://github.com/nagaseyasuhito/camellia</url> <connection> scm:git:git@github.com:nagaseyasuhito/camellia.git </connection> <tag>HEAD</tag></scm>!<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <configuration> <tagNameFormat>@{project.version}</tagNameFormat> <goals>package</goals> </configuration> </plugin> </plugins></build>

maven release plugin

mvn release:prepare release:perform

Jenkins Build

Pipeline Plugin

Unit Test

Integration Test Release

Production Deploy

Staging Deploy

Development Deploy

Clone workspace

SCM Plugin

GitHub

Clone workspace SCM

Unit Test

Integration Test

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0

as1.camellia camellia:1.0.0

as2.camellia camellia:1.0.0

Reverse Proxy

Production Deploy

通常時

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0 camellia:1.0.1

as1.camellia camellia:1.0.0

as2.camellia camellia:1.0.0

Reverse Proxy

Production Deploy

asadmin deploy --target=camellia --enabled=false --name camellia:1.0.1 /tmp/camellia:1.0.1.war

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0 camellia:1.0.1

as1.camellia camellia:1.0.0

as2.camellia camellia:1.0.0

Reverse Proxy

Production Deploy

リバースプロキシからas1.camelliaを抜く

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0 camellia:1.0.1

as1.camellia camellia:1.0.1

as2.camellia camellia:1.0.0

Reverse Proxy

Production Deploy

asadmin enable --target=as1.camellia camellia:1.0.1

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0 camellia:1.0.1

as1.camellia camellia:1.0.1

as2.camellia camellia:1.0.0

Reverse Proxy

Production Deploy

リバースプロキシにas1.camelliaを入れる

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0 camellia:1.0.1

as1.camellia camellia:1.0.1

as2.camellia camellia:1.0.0

Reverse Proxy

Production Deploy

リバースプロキシからas2.camelliaを抜く

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0 camellia:1.0.1

as1.camellia camellia:1.0.1

as2.camellia camellia:1.0.1

Reverse Proxy

Production Deploy

asadmin enable --target=as2.camellia camellia:1.0.1

Deploy to

GlassFish

camellia

das.camellia camellia:1.0.0 camellia:1.0.1

as1.camellia camellia:1.0.1

as2.camellia camellia:1.0.1

Reverse Proxy

Production Deploy

リバースプロキシにas2.camelliaを入れる

運用するぞ

http://www.flickr.com/photos/defenceimages/6331498981

logging

asadmin set-log-levels org.eclipse.persistence.session=FINE

logging

[#|2013-11-23T21:37:11.979+0900|INFO|glassfish 4.0|javax.enterprise.system.core|_ThreadID=101;_ThreadName=Thread-16;_TimeMillis=1385210231979;_LevelValue=800;_MessageID=NCLS-CORE-00022;| Loading application __admingui done in 6,277 ms|#]

[2013-11-23T21:39:41.869+0900] [glassfish 4.0] [INFO] [NCLS-CORE-00022] [javax.enterprise.system.core] [tid: _ThreadID=100 _ThreadName=Thread-16] [timeMillis: 1385210381869] [levelValue: 800] [[ Loading application __admingui done in 5,286 ms]]

com.sun.enterprise.server.logging.UniformLogFormatter

com.sun.enterprise.server.logging.ODLLogFormatter

JMX

@MXBeanpublic interface UserMonitor { long getNumberOfUsers();}

JMX

JMX

@Startup @Singletonpublic class UserMonitorImpl implements UserMonitor { @Inject private UserDao userDao;! @SneakyThrows @PostConstruct public void initialize() { ObjectName objectName = new ObjectName("Camellia:type=User"); MBeanServer server = ManagementFactory.getPlatformMBeanServer() if (server.isRegistered(objectName)) { server.unregisterMBean(objectName); } server.registerMBean(this, objectName); }! @Override public long getNumberOfUsers() { return this.userDao.count(); }}

LombokJMX EJB CDI

Demoデモしたい

Gangliaで出したい

jmetric

asadmin create-jvm-options '-javaagent\: ${com.sun.aas.instanceRoot}/lib/jmxetric-1.0.4.jar= config=${com.sun.aas.instanceRoot}/config/jmxetric.xml'

jmetric

<jmxetric-config> <jvm process="Camellia" />! <sample delay="300"> <mbean name="Camellia:type=User" pname="User"> <attribute name="NumberOfUsers" type="int16" /> </mbean> </sample>! <ganglia hostname="localhost" port="8649" mode="multicast" wireformat31x="true" /></jmxetric-config>

まとめ

Conclusionエンタープライズ言うな

Copyright © GREE, Inc. All Rights Reserved.

インターネットを通じて、世界をより良くする。

Copyright © GREE, Inc. All Rights Reserved.

top related