Weblogic Plugin to Set Deployment Order

WebLogic Server 12 has updates to the plugin that allow features such as being able to start/stop servers as well as run WLST scripting. The reason the WLST scripting is a beneficial feature is that the plugin is being used deploy all assets to a target environment (like wars, optional packages, and resources). In deploying all these resources through a build script, it becomes necessary to set the deployment order when assets have a dependency on a resource already being available prior to the asset being started during deployment or start-up of the managed server.

In order to modify the deployment order, a WLST script has to be used because the WebLogic Server 12 plugin does not support setting the deployment order through the maven script. So in order to utilize the newer WebLogic Server 12 maven plugin, it an install of WebLogic Server 12 so that it can utilize the install for running WLST scripts and other functioanility.

In the use case, the servers that exist within the environments is running 11g, however, in order to take advantage of this new feature, the build management system needs access to WebLogic Server 12c. As mentioned previously, this means that WebLogic Server 12 is installed on the build management box (in this case Hudson), so that the Hudson jobs have access to the install for WLST. The tests were ran utilizing the 12c version of the plugin to modify deployment orders on the 11g install and it worked. The only problem with running WLST scripts through Hudson builds is that doing multiple WLST scripts means opening a session with WebLogic Server and then closing that session, multiple times. This overhead is a memory hog and ultimately crashed the Hudson box. So the code/scripting is there to utilize the deployment order, but because of resource constraints, this functionality isn’t currently being used.

The following are the steps I took: 1) Installed WebLogic Server 12c to a local folder WLS_12C_MIDDLEWARE_PATH on the build server 2) Followed all steps from http://docs.oracle.com/cd/E24329_01/web.1211/e24368/maven.htm#CHEFAEBI for apache-maven-2.2.x. 3) Started the target Weblogic server 11g at (11g-IP-addr):7001 4) Edited a project pom.xml for deploying the war:

1
2
</p>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.oracle.test</groupid> <artifactid>sample2</artifactid><packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>sample2 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <finalname>sample-war</finalname><plugins><plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <configuration> <source>1.6 <target>1.6</target> </configuration> </plugin><plugin> <groupid>com.oracle.weblogic</groupid> <artifactid>wls-maven-plugin</artifactid> <version>12.1.1.0</version> <configuration> <adminurl>t3://(local-IP):7001</adminurl> <user>weblogic</user><password>weblogic1</password> <upload>true</upload> <action>deploy</action> <remote>false</remote> <verbose>true</verbose> <source>target/sample-war-10.war <name>sample-war-10</name> </configuration> <executions> <execution><phase>install</phase> <goals> <goal>deploy</goal> <goal>undeploy</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

5) Ran a maven command based on the pom for deploying sample-war-10.war:

1
 mvn wls:deploy -DmiddlewareHome=(WLS_12C_MIDDLEWARE_PATH)

I had to use -DmiddlewareHome because the element in pom.xml didn’t work. 6) Created the following WLST script for changing the deployment order (changeOrder.py):

1
2
3
4
5
6
 from java.util import * from javax.management import * import javax.management.Attribute
<p>
    print 'starting the script .... '
</p>
<p>
    connect('weblogic', 'weblogic1', "t3://(11g-IP-addr):7001") edit() startEdit() cd('AppDeployments') cd('sample') set ('DeploymentOrder', 115) save() activate() disconnect() exit()

7) Then incorporated that script within the wls-maven-plugin:

1
2
3
4
5
6
7
</p>
<plugin> <groupid>com.oracle.weblogic</groupid> <artifactid>wls-maven-plugin</artifactid> <executions> <execution><phase>package</phase> <goals> <goal>wlst</goal> </goals> </execution> </executions> <configuration>  from java.util import * from javax.management import * import javax.management.Attribute
<p>
    print 'Updating deployment order .... '
</p>
<p>
    connect(System.getProperty("deploy.user"), System.getProperty("deploy.password"), System.getProperty("deploy.admin")) edit() startEdit() cd(System.getProperty("deploy.mbean")) cd(System.getProperty("deploy.library.name")) set ('DeploymentOrder', System.getProperty("deploy.order")) save() activate() disconnect()

8) Then ran the WLST call from the maven plugin:

1
 mvn wls:wlst -DfileName=changeOrder.py -DmiddlewareHome=(WLS_12C_MIDDLEWARE_PATH)

Properties are fed into the python script from Maven properties (based on a profile which is different for applications, resources, and optional packages).

This is because within the JNDI hierarchy through WLST, these assets get different Types, different versions, and different name. We can see this by logging into the server through a WLST command window and simply running an ls() command on the application or library directory. For instance, the following is an example of running the ls() command on the war. We can see that the type is AppDeployment and that the Identifier and Name are similar.

1
 wls:/sandbox/serverConfig/AppDeployments/sample-war-10> ls() dr--   SubDeployments dr--   Targets -r--   AbsoluteInstallDir                           null -r--   AbsolutePlanDir                              null -r--   AbsolutePlanPath                             null -r--   AbsoluteSourcePath                           /domains/sandbox/servers/sandboxAdminServer/upload/sample-war-10/app/sample-war.war -r--   ApplicationIdentifier                        sample-war-10 -r--   ApplicationName                              sample-war-10 -r--   CompatibilityName                            null -r--   DeploymentOrder                              102 -r--   DeploymentPlan                               null -r--   DeploymentPlanExternalDescriptors            null -r--   DeploymentPrincipalName                      null -r--   InstallDir                                   null -r--   ModuleType                                   war -r--   Name                                         sample-war-10 -r--   Notes                                        null -r--   PlanDir                                      null -r--   PlanPath                                     null -r--   SecurityDDModel                              DDOnly -r--   SourcePath                                   servers/sandboxAdminServer/upload/sample-war-10/app/sample-war.war -r--   StagingMode                                  null -r--   Type                                         AppDeployment -r--   ValidateDDSecurityData                       false -r--   VersionIdentifier                            null -r-x   freezeCurrentValue                           Void : String(attributeName) -r-x   isSet                                        Boolean : String(propertyName) -r-x   unSet                                        Void : String(propertyName)

anabolic steroids for sale

Now we will run the same command, but this time on an Optional Package, like our cxfFull that we created with Apache Shade. We can see here that the type is Library instead of AppDeployment, and that the ApplicationIdentifier includes the Manifest versions identified for this Optional Package. Therefore we need to feed in different properties when attempting to change the deployment order for an application asset as opposed to a library asset.

1
 wls:/sandbox/serverConfig/Libraries/cxfFull#2.4.5@2.4.5> ls() dr--   SubDeployments dr--   Targets -r--   AbsoluteInstallDir                           null -r--   AbsolutePlanDir                              null -r--   AbsolutePlanPath                             null -r--   AbsoluteSourcePath                           /domains/sandbox/servers/sandboxAdminServer/upload/cxfFull/2.4.5@2.4.5/app/cxf-full.jar -r--   ApplicationIdentifier                        cxfFull#2.4.5@2.4.5 -r--   ApplicationName                              cxfFull -r--   CompatibilityName                            null -r--   DeploymentOrder                              95 -r--   DeploymentPlan                               null -r--   DeploymentPlanExternalDescriptors            null -r--   DeploymentPrincipalName                      null -r--   InstallDir                                   null -r--   ModuleType                                   null -r--   Name                                         cxfFull#2.4.5@2.4.5 -r--   Notes                                        null -r--   PlanDir                                      null -r--   PlanPath                                     null -r--   SecurityDDModel                              DDOnly -r--   SourcePath                                   servers/sandboxAdminServer/upload/cxfFull/2.4.5@2.4.5/app/cxf-full.jar -r--   StagingMode                                  null -r--   Type                                         Library -r--   ValidateDDSecurityData                       false -r--   VersionIdentifier                            2.4.5@2.4.5 -r-x   freezeCurrentValue                           Void : String(attributeName) -r-x   isSet                                        Boolean : String(propertyName) -r-x   unSet                                        Void : String(propertyName)

Of course, this can be easily done through the console, but the ability to do it through the usage of the Maven Plugin can speed up the deployment process. One of the ways that we could have sped up the utilization of this plugin would be to open a WLST session, modify the deployment order of all the assets we were deploying and then closed the WLST session. Instead of trying to open, modify, close a session for each asset that was being deployed.

Top Downloaded Mp3s

Share and Enjoy

Importance of a SOA Maturity Model

I talked a little about the Maturity Model concept in my blog entry about Simplifying Build Management – Build Once, Deploy Anywhere. One of the more well know Maturity Models is called CMMI (Capability Maturity Model Integration). In the presentation Capability Maturity Model Integration (CMMI) Version 1.2 Overview, there are descriptions of a “Process Model” that helps lay the foundation of the benefits of a Maturity Model.

A process model is a structured collection of practices that describe the characteristics of effective processes.
A process model is used

  • to help set process improvement objectives and priorities
  • to help ensure stable, capable, and mature processes
  • as a guide for improvement of project and organizational processes
  • with an appraisal method to diagnose the state of an organization’s current practices

The Maturity Model helps to define an architectural framework, what different levels of implementation can be achieved with the framework, ability to measure improvement of its usage, and the ability to assess the state of that architectural framework. The Maturity Model puts a subject like SOA into a framework and creates multiple maturity levels that define initial stages, all the way to advanced stages of the SOA process. This tutorial site provides a clear definition around what a maturity level is:

A maturity level is a well-defined evolutionary plateau toward achieving a mature software process. Each maturity level provides a layer in the foundation for continuous process improvement.

So we essentially have two maturity models that we are leaning on with regards to the standup of our SOA initiative. The initial example is from a document written in 2005 by Sonic Software Corporation (A NEW SERVICE-ORIENTED ARCHITECTURE (SOA) MATURITY MODEL). This provides an excellent example view into the different layers of a SOA Maturity Model and then finer grained discussions around each level. The following is the example Service-Oriented Maturity Model from this document:

soamm

We can see from this model that we have 5 essential levels for achieving SOA. The 5 maturity levels defined here are Initial Services, Architected Services, Business/Collaborative Services, Measured Business Services, and Optimized Business Services. These different maturity levels allow us to evolve our SOA initiative over time and validate that we are correctly progressing through those levels. For instance, one of the recommended steps for implementing an SOA is to utilize a Enterprise Service Bus to stand up some initial services (in order to create a starting point). It’s easy to determine the success of the overall SOA initiative based on this initial phase, which might give a view that the SOA initiative is not successful. This might be because the right types of services are not being exposed, or composite services aren’t being created, advanced standards aren’t developed, and so forth. But in the context of a Maturity Model, it allows us to evaluate our current SOA initiative against the different levels and determine that we have successfully achieved Level 1, lining up what is necessary for us to move towards Level 2 of the Maturity Model.

primobolan depot

Another Maturity Model for SOA is provided at Griffiths Waite – the Oracle SOA company. This is defined more clearly in the resource document SOA Maturity Model – Quick Reference Guide.

SOA-maturity-model-large

This Maturity Model also provides 5 phases called Opportunistic, Systematic, Enterprise, Measured, and Industrialised. This documents the evolution of SOA from initial services, to the development of standards, to utilizing BPEL for integration of multiple services, then utilizing BAM to monitor and measure services, to the ability to be completely agile via the previously successfully implemented 4 phases.

The following article provides a landing page for quite a few different SOA Maturity Models.

The fact is that starting a SOA initiative is a massive undertaking with many moving pieces and steps. It is easy to become overwhelmed as to the correct processes and architecture necessary to achieve the SOA end state. The benefit of aligning these initiatives with a SOA Maturity Model is that we are able to partition our SOA intiative into individual levels/stages so that we can achieve SOA in more manageable chunks. At the end of each phase of our SOA, we can determine whether or not we have evolved to the next phase of the SOA Maturity Model and what is left to accomplish our current level.

Share and Enjoy

Configuring Logback in a Web Application

When developing web applications in the past, most of them used Log4J for doing logging. Logging statements in the application utilized the Log4J API to log debugging statements or issues, etc at different logging levels. The general configuration for enabling the logging statements was to put a Log4J configuration file on the server that applied to all the applications that were running on the server. This configuration file will set the logging statement format, logging levels per API, and potential Appenders to determine where to write the output (log files or standard out). It was not a simplistic process to enable different logging levels for an API per application because of the implementation of the logging framework.

With the advent of Logback and a change in the design to how logging was being configured, this was simplified through the following process. Logback is being used in conjunction with SLF4J, SLF4J providing the logging facade and Logback being the logging provider to that facade. This is simply done by including Logback configurations and jars within the application.

In this specific architecture, there are many service endpoints running in their own web application resource and therefore would benefit from an ability to have their own specific logging. This would enable logging levels to be set low or higher for a specific service based on runtime issues or debugging needs. The question with regards to this is if there is a configuration file per web application, then how would we tie the configuration file to the specific web application that is supposed to use it. In this case, we can take advantage of a feature in Logback called File Inclusion. This will allow us to separate parts of the logging configuration and include that separate fragment into the main logging configuration.

Now that we are aware that we can split the configuration into smaller files, we need to determine what requirements we have and what types of files that will produce. One of the initial requirements is the ability to dynamically change the logging levels without redeploying the war (and at this point we are not considering the ability to change the logging framework levels via JMX and the Application Server console). The requirement to dynamically change the logging levels will drive a second requirement, which is the configuration files will need to be placed on the server so that they can be modified outside of the WAR file. The third requirement is driven around the need to tie the configuration on the server to the specific WAR file that will be using it and this can be accomplished by placing a configuration file within the WAR file.

As we look through this general description, the architecture for the logging configuration will require two logging configuration files (one on the server and one within the WAR file). The logging configuration on the server only has the requirement for changing logging levels so we can just put the logger (API) configurations within this file. Since the location of the logging statements and output format won’t need to change dynamically, this configuration will go into the logging file within the WAR.

So our first configuration file will be the file that exists on the server. This will utilize the included element in order to identify that this configuration file is a fragment of a larger configuration. This also provides an appender, but it is the appender for the stdout so that it can be customized for debugging purposes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<included>
 
  <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
     <encoder>
    <pattern>%d THREAD:[%thread] %level ID:[%X] %logger - %m%n</pattern>
     </encoder>
  </appender>
 
  <logger name="org.apache.cxf" level="info" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="org.apache" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
   
  <logger name="org.hibernate.ejb" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="org.hibernate" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="org.hibernate.sql" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="org.quartz" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="org.springframework" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>

  <logger name="org.springframework.transaction" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="com.foo.frmwk.service.interceptor.PolicyPointcutInterceptor" level="info" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="PerformanceLogger" level="debug" additivity="false">
    <appender-ref ref="SampleWebApplicationPerformance"/>
  </logger>
 
  <logger name="com.foo.service" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="com.foo.frmwk" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>
 
  <logger name="com.foo.frmwk.dao.interceptor" level="warn" additivity="false">
    <appender-ref ref="SampleWebApplication" />
  </logger>

  <root level="warn">
    <appender-ref ref="stdout" />
    <appender-ref ref="SampleWebApplication"/>
  </root>
</included>

This next file is the main logback.xml configuration which exists within the WAR file that is deployed on the server. This configuration file an include for including the previous file that lives on the physical server. It is able to resolve the file because the directory where all the appender logback.xml configurations live on the server is put into the classpath of the application servers start scripts. The other item to mention is the scanPeriod, which sets how often the configuration checks for changes. This allows the logback.xml file on the server to be changed and the WAR’s Logback instance to pickup these changes and reflect them within the log file output. This allows us to add additional loggers as well as changing log levels on the fly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<configuration scan="true" scanPeriod="30 seconds">

  <appender name="SampleWebApplication" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>./logs/services/SampleWebApplication.log</file>
    <append>true</append>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>./logs/services/archive/SampleWebApplication%d{yyyy-MM-dd}.log</fileNamePattern>
     
      <!-- keep 30 days worth of history -->
      <maxHistory>10</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>%d [%thread] %level %logger - %m%n</pattern>
    </encoder>
  </appender>

  <appender name="SampleWebApplicationPerformance" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>./logs/services/SampleWebApplicationPerformance.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>./logs/services/archive/SampleWebApplicationPerformance%d{yyyy-MM-dd}.log</fileNamePattern>
     
      <!-- keep 30 days worth of history -->
      <maxHistory>10</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>%d [%thread] %level %logger - %m%n</pattern>
    </encoder>
  </appender>

  <include resource="SampleWebApplication-logback.xml"/>
 
</configuration>

Share and Enjoy