1. Trang chủ
  2. » Công Nghệ Thông Tin

Bắt đầu với IBM Websphere smash - p 26 pps

10 240 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 496,52 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Then, for each process you want to execute, add a timer task entry and event handler into the zero.config file... When the task ticks, it fires a “timer” event, and sets the event task name

Trang 1

Listing 9.15 Application Code to Call a Secured Service

def callDataService( args ) {

logger.INFO {"Starting with: ${args}"}

def URL = "https://crownjewels.acme.com/resources/${args.service}"

if ( args.id ) {

URL += "/${args.id}

}

args.remove('service')

args.remove('id')

args.eachWithIndex() { it, idx ->

URL += (idx == 0 ? '?' : '&' ) +

URLEncoder.encode(it.key, "UTF-8") + "=" +

URLEncoder.encode(it.value, "UTF-8")

}

logger.INFO {"URL: ${URL}"}

def response = Connection.doGET(URL)

def doc = new XmlParser().parse( response.responseBody )

logger.INFO {"Results : ${doc}"}

return doc

}

In this example, we make a dynamic call to some service as defined by the method

parame-ters, and receive an XML document as a response It is a big assumption that we will be receiving

an XML response, but this serves for this example If you are expecting a response other than

XML, adjust the response handler to process the correct data type

Let’s examine this bit of reusable code a little more In the first several lines, we build up

the base URL The static part of that URL should really be defined as an entry in the application

config file, and not a static string as shown in this example

We supply the actual service to be called in the args.service entry, and if supplied, we add

on the resource ID

Next, we remove the service and ID entries from the argument map, and then walk the

remain-ing args and append them to the URL as parameters Encodremain-ing the parameters is necessary because

the parameters might include characters that are not transmittable in their original encoding

Finally, we open a GET connection to the URL and pull in the results as an XML

docu-ment There is a lot more we could do to improve this method, such as dynamically handling

dif-ferent response data formats, but at least you should be able to see how easy it is to make secure

connection calls to remote services

Download from www.wowebook.com

Trang 2

Conclusion

In this chapter, we have taken a whirlwind tour of various security subsystems within the

Web-Sphere sMash environment There is a lot we didn’t cover about various configuration options

within each security scenario The documentation provided on the Project Zero website goes

deeper into the security details The goal of this chapter was to give you the basics needed to

cre-ate a secure WebSphere sMash application The information learned in this chapter is directly

usable in real-world applications

Trang 3

This page intentionally left blank

Download from www.wowebook.com

Trang 4

In this chapter, we discuss a variety of WebSphere sMash capabilities and provide an insight as to

when you can use these features to add greater flexibility to your application For instance, there

are often times when an application cannot simply rely on the standard request/response cycle

dictated by the user’s browser You may want to perform some preparation work upon application

initialization and not force the first user in to bear the brunt of the extra processing delay There

may be times where you want your application to periodically check in with another server, pull

in news feeds, or send usage statistics to a monitoring site The scenarios are limitless and may

not fall within the normal traffic patterns of your users

WebSphere sMash provides several features to assist you in processing data based on

vari-ous events These events can be regular and cyclical in nature, where a timer can initiate an event,

or you may need to watch a file system for changes and process those files There are also

facili-ties for watching POP mail accounts for new mail, and queues can receive asynchronous

mes-sages as part of the Reliable Transport Extension (RTE)

A large network of connected applications can also use WebSphere sMash to communicate

without any users or browsers being involved in the mix This opens the door to a wide array of

internetworked applications that can stay in contact with each other

Timers

A timer is used to fire re-occurring events The timer ticks at predetermined intervals, and a

han-dler event method called onTimer()can then take any required actions

To use timers, you need to add the zero.timer dependency to the application’s ivy.xml file

Then, for each process you want to execute, add a timer task entry and event handler into the

zero.config file By convention, you should place your timer handler scripts into a directory

C H A P T E R 1 0

Event Processing

Trang 5

called /app/scripts/timers This is just a recommendation; you can organize your code as

you see fit

In the configuration snippet shown in Listing 10.1, we define a timer named “heartbeat,”

which fires every 30 seconds, and call the onTimermethod of the /app/scripts/timers/

heart-beat.groovy file In the first line, we define the timer task A timer task is an object that has a

single property called a “delay,” or the tick time in seconds When the task ticks, it fires a “timer”

event, and sets the event task name to the ending name of the timer task, which in our sample is

“heartbeat.” For every timer task, there is a corresponding handler block The handler block

con-sists of an events type of timer, with conditions matching the event’s task name to the timer’s task

name The handler determines the script to call for the doTimermethod The instanceData

member contains a map of arguments that are passed into the onTimermethod

Listing 10.1 Timer Configuration

/config/timer/tasks/heartbeat = { "delay" : 30 }/config/handlers += [{

"events" : "timer",

"conditions" : "/event/_taskName =~ heartbeat",

"handler" : "timers/heartbeat.groovy",

"instanceData" : {

"myArg1" : "someConfigurableValue"

}

}]

So, what do we put into our doTimermethod? Well, that can basically be whatever you want

The instanceDatavariables are accessible from the “event” global context So, in our sample

configuration, the doTimermethod can grab the instance data using zget(“/event/myArg1”)

Listing 10.2 shows our handler code located in the file: /app/scripts/timers/heartbeat.groovy

Listing 10.2 /app/config/timers/heartbeat.groovy

package timers

def onTimer() {

logger.INFO{"Heartbeat timer fired"}

logger.INFO{"Event name: " + zget("/event/_taskName")}

logger.INFO{"Event Instance Data MyArg1 : " + zget("/event/myArg1") }

}

Start the application, and let’s see what we get produced to the console Nothing Hmm,

even waiting 30 seconds, and we get nothing The reason for this is that the timer is not fired

until a request comes into the ZSO, which then actually starts up the application So, use your

Download from www.wowebook.com

Trang 6

browser to access the application (http://localhost:8080) The browser displays the normal sMash

“up and running” page, whereas the console log shows our logging output We can take away a

few things from this test First, timers by default start only when the ZSO has activated the

appli-cation, and by consequence, they also stop firing when the ZSO idles the application We’ll

address this seemingly erratic behavior momentarily The other thing to notice on this little

sample is that a timer event fires immediately when the application is initialized, and then upon

each tick’s delay value This can be used to our advantage for using a timer to perform a one-time

application initialization

By default, the timer will not start until the first request comes in and the ZSO initiates the

application If you need the timer to start as soon as the application initializes, set the following in

the zero.config; the timer fires immediately and then at the defined intervals:

/config/zso/immediateStart=true

By default, the ZSO starts an application when a request comes in on one of the listening

ports At this point, ZSO starts the application and subsequently the timer service After a period

of inactivity, ZSO closes down the application and therefore the timers that are running within

that application If you set the ZSO immediateStartflag, ZSO immediately starts the

applica-tion and allows the timer to fire Depending on the delay time of the timer, the ZSO may still shut

down the application, but the timer(s) continues to fire at the appropriate intervals, forcing the

ZSO to bring the application back up into listening mode

Application Initialization Using Timers

One common use of a timer is to perform a one-time application initialization As stated earlier, a

timer is fired immediately upon application startup and then at each delay interval So, to force an

application to perform a single startup, set the delay time to a very large value It will fire one

time, and remain dormant thereafter The only issue to resolve is to ensure that initialization has

completed before any user requests are processed When the application is run under the ZSO,

this race condition is even more likely The solution is to use an initialization flag

When a request comes into the ZSO for an application, the ZSO starts up the application,

which immediately fires the timer event The timer event and the servicing of the request happen

in parallel, which means that each entry point or starting page of the application needs to check

for initialization before continuing and actually servicing the request Let’s go through a quick

example of using an initialization flag

First, create a new inittimer, with a delay time of 9999999 (or any ridiculously large

value) and an event handler stanza, as shown in Listing 10.3 A value this large (~3 years) will

ensure that our timer never fires again This is essentially the same as our first example, but this

time, we are not defining any instanceDatavalues

Trang 7

Listing 10.3 Initialization Timer Configuration

/config/timer/tasks/init = { "delay" : 99999999 }

/config/handlers += [{

"events" : "timer",

"conditions" : "/event/_taskName =~ init",

"handler" : "timers/init.groovy"

}

The /app/scripts/timers/init.groovy::onTimermethod shown in Listing 10.4

performs whatever initialization processes our application requires In this sample, we just put the

thread to sleep for several seconds to simulate some rather long database activity After the

ization has completed, we set an application-level context flag to indicate that we are fully

initial-ized and ready to accept incoming requests This is all well and good, but what if a request comes in

before our flag is set? We need to create a blocking method that holds the request(s) until the

appli-cation is initialized This is represented in the ”waitForInitialized”method This method

simply enters a time-delayed loop waiting for the proper initialization flag to be set Although it is

probably not a great practice to sleep your request threads, it can come in handy in this situation

Listing 10.4 /app/scripts/timers/init.groovy

package timers

def onTimer() {

try {

if ( ! zget("/app/initialized") ) {

logger.INFO{ "Initializing application - " +

"from timer task (${event._taskName[]})" }

Thread.currentThread().sleep(30000) // 30 sec

zput( "/app/initialized", true )

logger.INFO{ "Initialization completed." }

}

} catch ( e ) {

logger.SEVERE{ "Initializing error - ${e}" }

}

}

def waitForInitialized() {

def x = 0

while ( ! app.initialized[] ) {

logger.INFO{ "Waiting for initialization to complete ${++x}" }

Download from www.wowebook.com

Trang 8

Thread.currentThread().sleep(1000) // 1 sec

}

return true

}

The only thing we have left to do is to add the call to our waitFormethod in each

pos-sible web page of the application We show a sample of this in Listing 10.5, showing us a simple

index.gt file Although this sort of waiting for initialization process becomes cumbersome to

manage if there are many potential entry pages into your application, it does solve a rather

thorny issue

Listing 10.5 /public/index.gt

<% invokeMethod("timers/init.groovy", "waitForInitialized", null ) %>

<html>

<head>

<title>Init Test</title>

</head>

<body>

<h1>Hello!</h1>

</body>

</html>

Test out our initialization process by starting the application and quickly attempting to

access the main page The browser should be forced to wait several seconds before the ready flag

is set and the rendering is permitted to continue Check the log file to verify that the proper

sequence of events has taken place

There are other ways that you can explore to gain both a functional application

initializa-tion and still maintain the benefits of using ZSO to manage overall applicainitializa-tion resources One

entails having a dedicated “timer” application that is always running and firing events This

assumes that the initialization is for more generic resources, such as databases, file systems, or

other remote resources The timer application can also “kick” other applications and delivery

information at regular intervals We discuss kickers in the next section If you have a cluster of

related applications on a single host, organizing timed events around a single long-running

“timer” application can solve a lot of issues with the individual applications running cyclical

events, while still allowing the ZSO to manage the other application instances

Kickers

There are several different styles of kickers that we cover in this chapter The purpose of a kicker

Trang 9

Table 10.1 Common Kicker InstanceData Members

InstanceData

Configuration Members

Description

receiverURL The target URL to receive the “kick” notification This is a

required variable for all kickers Despite its name, you may also use a connection name instead of an actual URL for this field

maxRetries The number of times to attempt to kick the remote application

The default is five retries

maxDelay This is the delay time between failed kick attempts The default

is 5 seconds between retries

map This is typically used to supply the username and password under basic authentication connections This is an options setting based on your requirements

has been made, or the number of configured retries has been exceeded Kickers use the timer

sub-system discussed previously to perform a kick, or test for conditions that will invoke a kick

action The kick call returns either success or failure based on the status code returned from the

POST call to the remote application

To enable kicker support in your application, you need to add the appropriate zero.kicker

module into the ivy.config There are a few new instanceDatavariables that go into the event

stanza for each type of kicker, which we need to define in the configuration file Other kicker

types also have their own instanceDatavariables, which we’ll point out shortly The variables

that are shared among all kickers are shown in Table 10.1 We’ll look at sample configurations for

each kicker

As a matter of consistency and convention, it is recommended that you place all kicker

han-dlers under the ”/app/scripts/kickers” Of course, you are free to place them wherever

makes sense to you and your application structure

Simple Kicker

The most basic kicker simply calls a handler on each timer tick, passing in the variables defined

in the instanceDatablock from the configuration file It’s simply a matter of calling the kick

function from your custom handler This will perform a POST to the designated receiverUrl,

passing in a map of the parameters passed into the kick method

Let’s build a simple kicker to illustrate this concept and look at what the receiving

applica-tion delivered First, add the ”zero.kicker”module to the ivy.config file Next, create a timer

Download from www.wowebook.com

Trang 10

and event stanza in your application’s configuration file, as shown in Listing 10.6 Remember that

timers will not fire when the application is idled by the ZSO, so make sure you set the

immediateStartflag to true

Listing 10.6 Simple Kicker Configuration

/config/zso/immediateStart=true /config/timer/tasks/myKicker = { "delay"

: 120 }

/config/handlers += [{

"events" : "timer",

"conditions" : "/event/_taskName =~ myKicker",

"handler" : "kickers/mySimpleKicker.groovy",

"instanceData" : {

"receiverUrl": "http://localhost:8080/resources/kickReceiver"

}

}]

We create a standard timer with a two-minute tick delay, and a corresponding handler that

calls ”mySimpleKicker.groovy”, which is shown in Listing 10.7 Notice how we define the

receiverUrl Under normal circumstances, this would point to a different application, likely

residing on a different host For this sample, we’ll just call a resource in the same application

Listing 10.7 /app/scripts/kickers/mySimpleKicker.groovy

import zero.kicker.Kicker

def onTimer() {

def args = [

"arg1": "Test message",

"number1" : "234"

]

logger.INFO{ System.currentTimeMillis() +

": mySimpleKicker: sending: " + args }

def kickOk = Kicker.kick( args );

logger.INFO{ System.currentTimeMillis() +

": mySimpleKicker: kickOk: " + kickOk }

}

There is actually a lot to inspect in this little bit of code First, we import our Kicker class,

which contains several variations of the kick()method This simplest and most common class

accepts a map of arguments to be sent to the remote host The URL is automatically retrieved

Ngày đăng: 06/07/2014, 19:20

TỪ KHÓA LIÊN QUAN