ESB-configuration-example
Request Flow ——————
# EIP service engine
<beans xmlns:eip=”http://servicemix.apache.org/eip/1.0″
xmlns:esb=”http://esbinaction.com/examples”>
<!– input, if s.o. send msg to endpoint, automatically send to output. –>
<eip:static-recipient-list service=”esb:bookRecipientPipeline”
endpoint=”bookRecipientPipelineEndpoint”>
<!– output –>
<eip:recipients>
<eip:exchange-target service=”esb:loggerComponent”/>
<eip:exchange-target service=”esb:amazonRequest”/>
<eip:exchange-target service=”esb:transformBarnesPipeline”/>
</eip:recipients>
</eip:static-recipient-list>
</beans>
# SM-Saxon
<beans xmlns:saxon=”http://servicemix.apache.org/saxon/1.0″
xmlns:esb=”http://esbinaction.com/examples”>
<!– service name –>
<saxon:xslt service=”esb:transformToBarnes”
endpoint=”toBarnesEndpoint”
resource=”classpath:IsbnToBarnes.xslt” />
</beans>
# Pipeline
<!– input –>
<eip:pipeline service=”esb:transformBarnesPipeline”
endpoint=”transformBarnesPipelineEndpoint”>
<eip:transformer>
<eip:exchange-target service=”esb:transformToBarnes” />
</eip:transformer>
<eip:target>
<eip:exchange-target service=”esb:barnesRequest” />
</eip:target>
</eip:pipeline>
# AggregatorMessageLogger SM-Bean
public void onMessageExchange(MessageExchange exchange)
throws MessagingException {
if (exchange.getStatus() != ExchangeStatus.ACTIVE) {
logger.info(“state is not active so ignoring call”);
return;
}
Element payloadElem = null;
try {
Source contentSource = getInMessage(exchange).getContent();
payloadElem = sourceTransformer.toDOMElement( Converts message
contentSource); to DOM object
} catch(Exception e) {
logger.error(“error while reading payload”, e);
throw new MessagingException(e);
}
BookQuote bookQuote = QuoteMessageHelper. Transforms to
unmarshallQuote(payloadElem); BookQuote
logger.info(“received quote ” + bookQuote.getIsbn() + “, “
+ bookQuote.getPrice() + “, ” + bookQuote.getCompanyName());
NormalizedMessage outMessage = Creates response
exchange.createMessage(); message
try {
outMessage.setContent(new StringSource(
QuoteMessageHelper.marshallQuote(bookQuote)));
} catch(Exception e) {
logger.error(“error while setting content in out message”, e);
throw new MessagingException(e);
}
outMessage.setProperty( Sets correlation
“org.apache.servicemix.eip.splitter.corrid”, identifier
bookQuote.getIsbn());
Integer aggregatorIndex = null;
if(“Amazon”.equalsIgnoreCase(bookQuote.getCompanyName())) {
aggregatorIndex = new Integer(0);
} else if(“BarnesAndNoble”.equalsIgnoreCase(
bookQuote.getCompanyName())) {
aggregatorIndex = new Integer(1);
}
outMessage.setProperty( Sets message
“org.apache.servicemix.eip.splitter.index”, index
aggregatorIndex);
outMessage.setProperty( Sets group
“org.apache.servicemix.eip.splitter.count”, size
new Integer(2));
exchange.setMessage(outMessage, “out”);
channel.send(exchange);
}
<eip:split-aggregator service=”esb:quoteAggregator”
endpoint=”quoteAggregatorEndpoint”>
<eip:target>
<eip:exchange-target service=”esb:cheapestPricePipeline”/>
</eip:target>
</eip:split-aggregator>
SM-EIP service engine configuration ServiceMixion
<eip:content-based-router service=”esb:simplerouter” (Defines type
endpoint=”routerEndpoint”> of router)
<eip:rules>
<!– # 1st routing rule –>
<eip:routing-rule> (Adds routing
<eip:predicate> rule)
<eip:xpath-predicate
xpath=”/esb:order/esb:type=1″ (Evaluates incoming
namespaceContext=”#nsContext” /> message)
<!– if type=1–>
</eip:predicate>
<!– forward msg to service –>
<eip:target> (Targets service
<eip:exchange-target service=”esb:orderService1″ />
</eip:target> for routing rule)
</eip:routing-rule>
<!– # 2nd routing rule –>
<eip:routing-rule> (Adds another
<eip:predicate> routing rule)
<eip:xpath-predicate xpath=”count(/esb:order/esb:type)=2″
namespaceContext=”#nsContext” />
</eip:predicate>
<eip:target>
<eip:exchange-target
service=”esb:orderService2″ />
</eip:target>
</eip:routing-rule>
<!– # 3rd routing rule –>
<eip:routing-rule> (Targets service
<!– w/o predicate ( default rule) –>
<eip:target> for default rule)
<eip:exchange-target service=”esb:orderService3″ />
</eip:target>
</eip:routing-rule>
</eip:rules>
</eip:content-based-router>
<eip:namespace-context id=”nsContext”> (Defines namespace for
<eip:namespaces> XPath expression)
<eip:namespace
prefix=”esb”>http://opensourceesb/architecture
</eip:namespace>
</eip:namespaces>
</eip:namespace-context>
SOAP connect to sugarCRM
original in sugarWiki
However, it’s better to create new soap client using code from palmtree here
if you wanna create contact, just change module_name from ‘Leads’ to ‘Contacts’
For instance,
<?php
define('sugarEntry', TRUE);
//Use the NuSOAP files
require_once('lib/nusoap.php');
$soapclient = new nusoap_client('http://localhost/SugarCRM/soap.php?wsdl', true);
$err = $soapclient->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
$user_auth = array(
'user_auth' => array(
'user_name' => 'admin',
'password' => md5('yourpassword'),
'version' => '0.1'
),
'application_name' => 'soapleadcapture');
$result_array = $soapclient->call('login', $user_auth);
$err = $soapclient->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
$session_id = $result_array['id'];
$user_guid = $soapclient->call('get_user_id',$session_id);
$err = $soapclient->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
// Up until now, we have not introduced anything new
// The following lines will use the set_entry SOAP call to add
// a Lead from a mixture of POST variables and hard coded
// values, then assign to the authenticated Sugar user...
$set_entry_params = array(
'session' => $session_id,
'module_name' => 'Contacts',
'name_value_list'=>array(
array('name'=>'first_name','value'=>$_POST['first_name']),
array('name'=>'last_name','value'=>$_POST['last_name']),
array('name'=>'status', 'value'=>'New'),
array('name'=>'fos_c', 'value'=>$_POST['fos_c']),
array('name'=>'phone_work', 'value'=>$_POST['phone']),
array('name'=>'phone_fax', 'value'=>$_POST['fax']),
array('name'=>'account_name','value'=>$_POST['companyname']),
array('name'=>'lead_source','value'=>'Web Site'),
array('name'=>'description','value'=>$_POST['prod_desc']),
array('name'=>'assigned_user_id', 'value'=>$user_guid)));
$result = $soapclient->call('set_entry',$set_entry_params);
$err = $soapclient->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
// this redirects to a page specified in the previous page...
// header("Location: " . $_POST['redirect']);
?>
<pre>
<?
if ($result)
print_r($result);
?>
</pre>
<form action="" method="post">
first name : <input type="text" name="first_name"/><br/>
last name : <input type="text" name="last_name"/><br/>
phone : <input type="text" name="phone"/><br/>
fax : <input type="text" name="fax"/><br/>
company name : <input type="text" name="companyname"/><br/>
product desc : <input type="text" name="prod_desc"/><br/>
Field of study : <input type="text" name="fos_c"/><br/>
<input type="submit"/>
</form>
Query data———————–
<?php
define('sugarEntry', TRUE);
//Use the NuSOAP files
require_once('lib/nusoap.php');
$soapclient = new nusoap_client('http://localhost/SugarCRM/soap.php?wsdl', true);
$user_auth = array(
'user_auth' => array(
'user_name' => 'admin',
'password' => md5('yourpassword'),
'version' => '0.1'
),
'application_name' => 'soapleadcapture');
$result_array = $soapclient->call('login', $user_auth);
$err = $soapclient->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
print_r($result_array);
echo "test";
$session_id = $result_array['id'];
$user_guid = $soapclient->call('get_user_id',$session_id);
$err = $soapclient->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
// Up until now, we have not introduced anything new
// The following lines will use the set_entry SOAP call to add
// a Lead from a mixture of POST variables and hard coded
// values, then assign to the authenticated Sugar user…
$set_entry_params = array(
'session' => $session_id,
'module_name' => 'Contacts',
'query' => 'fos_c=\'CS\'',
'order_by' => 'contacts.first_name',
'offset' => 0,
'select_fields'=> array('first_name', 'phone_fax', 'fos_c'),
'max_results'=>3,
'deleted'=>0);
$result = $soapclient->call('get_entry_list',$set_entry_params);
$err = $soapclient->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
// this redirects to a page specified in the previous page…
// header("Location: " . $_POST['redirect']);
?>
<pre>
<?
if ($result)
print_r($result);
?>
</pre>
EJB QL example
Query query = manager.createQuery(
“SELECT c.firstName, c.lastName FROM Customer AS c”);
List results = query.getResultList( );
Iterator it = results.iterator( );
while (it.hasNext( )) {
Object[] result = (Object[])it.next( );
String first = (String)result[0];
String last = (String)result[1];
}
m-1, 1-1 : juz .(dot)
SELECT c.creditCard FROM Customer AS c
SELECT c.address.city FROM Customer AS c
SELECT c.creditCard.creditCompany.address FROM Customer AS c
SELECT new com.titan.domain.Name(c.firstName, c.lastName) FROM Customer c
*-m
SELECT new com.titan.domain.Name(c.firstName, c.lastName) FROM Customer c
Join
collection-valued properties, we use joins rather than property
navigation.
inner join
SELECT r FROM Customer AS c, IN( c.reservations ) r
หรือ SELECT r FROM Customer AS c, INNER JOIN c.reservations r
อีกตัวอย่าง SELECT cbn.ship FROM Customer
AS c, IN( c.reservations ) r, IN( r.cabins ) cbn
outer join
SELECT c.firstName, c.lastName, p.number
FROM Customer c LEFT JOIN c.phoneNumbers p
This query might return the results
David Ortiz 617-555-0900
David Ortiz 617-555-9999
Trot Nixon 781-555-2323
Bill Burke null
google app engine 9 ( user api )
import ก่อน
from google.appengine.api import users
เอา user ปัจจุบันมาโดย
user = users.get_current_user()
เราสามารถ print user.nickname() หรือ user.email() ได้
แล้ว users ยังมี method ไว้เอา login_url หรือ logout_url ออกมาด้วย
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = ‘Logout’
else:
url = users.create_login_url(self.request.uri)
url_linktext = ‘Login’
google app engine 8 ( file upload )
ตัวอย่างเลยละกัน
<form action=”.” method=”post” enctype=”multipart/form-data”>
<label>File: </label><input name=”file” type=”file”><br />
<input type=”submit”>
</form>
Server side:
class Image(db.Model):
name = db.StringProperty()
content = db.BlobProperty()
class UploadImage(webapp.RequestHandler):
def post(self):
if ‘file’ not in self.request.POST:
self.error(400)
self.response.out.write(“file not specified!”)
return
if (self.request.POST.get(‘file’, None) is None or
not self.request.POST.get(‘file’, None).filename):
self.error(400)
self.response.out.write(“file not specified!”)
return
file_data = self.request.POST.get(‘file’).file.read()
file_name = self.request.POST.get(‘file’).filename
im = Image()
im.name = file_name
im.content = file_data
im.save()
self.response.out.write(“image %r saved.” % im.name)
ตามนั้นแหละ
reference : http://popcnt.org/2008/05/google-app-engine-tips.html
google app engine 7 ( datastore )
เห็นเขาว่าเหมือน Django’s data modelling API แต่ว่า scalable กว่า
ก่อนอื่นต้อง import module db มาก่อน
from google.appengine.ext import db
จากนั้นประกาศโมเดล ลองเขียนหลายๆชนิดดังนี้
class Greeting(db.Model) :
author = db.UserProperty() # User
content = db.StringProperty(multiline=True) # String ( multiline (optional) : this property can contain newline characters )
text = db.TextProperty() # long String
date = db.DateTimeProperty(auto_now_add=True) # DateTime ( auto_now_add=True : ใส่ค่า default เป็น now ถ้าไม่ได้กำหนดค่าให้มัน )
ดูชนิดได้ ตามนี้
อื่นๆ ดูได้จาก datastore reference
Create/Update
สมมติว่ามีหน้าฟอร์มโพสมาที่หน้านี้แล้ว
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get(‘content’)
greeting.put() # saves our new object to the datastore ถ้ามีอยู่แล้วจะ update มัน
self.redirect(‘/’)
หรือจะเล่นแบบนี้เลยก็ได้ ง่ายดี
greeting = Greeting(author = users.get_current_user(), content = self.request.get(‘content’))
greeting.put()
select
greetings = Greeting.all()
จะ order หรือ where ก็ได้
greetings = Greeting.all()
greetings.filter(“author =”, users.get_current_user())
greetings.order(“-date”)
greetings_query.fetch(10)
หรือจะเอามายำๆอยู่บรรทัดเดียวกันก็ได้
greetings_query = Greeting.all().order(‘-date’)
greetings = greetings_query.fetch(10)
จากนั้น
{% for greeting in greetings %}
{{ greeting.key.id }} # คีย์ของแต่ละเรคอร์ด
{{ greeting.author }}
{{ greeting.content }}
{% endfor %}
count ได้ด้วยนะ
greetings.count()
greetings[0]
เรายังสามารถ get_by_id ได้ด้วย Greeting.get_by_id(greeting_id)
นอกจากนี้เรายังสามารถเขียน query ไปตรงๆ โดยใช้ gql ก็ได้
if users.get_current_user():
greetings = Greeting.gql(“WHERE author = :1 ORDER BY date DESC LIMIT 20″,
users.get_current_user())
หรือ
greetings = Greeting.gql(“WHERE author = :author ORDER BY date DESC”,
author=users.get_current_user())
NOTE :
- สามารถจัดการ data ที่เก็บไว้แล้วได้จาก http://localhost:8080/_ah/admin/datastore
( Entity Kind คือ ชื่อ Object )
ซึ่งมี interactive console ไว้ให้เล่นด้วย เด็ดจริงๆ
ถ้าจะเล่นกับ Model ในนั้น ต้อง import มันเข้ามาก่อน
from main import Greeting
- ถ้าต้องการ Clear Development Server Datastore
ตอน start server
$ dev_appserver.py –clear_datastore helloworld/
- ปกติมันจะสร้าง datastore ไว้ใน temp ในเครื่องของเรา ถ้าไม่อยากให้มันหายไปตอนเรารีสตาร์ท ให้กำหนด
--datastore_path=Folder ตอน dev_appserver
google app engine 5 ( template variable )
{{ variable_name }}
มี Filter ให้ใช้เหมือน smarty เลยแหะ
{{ variable_name|escape|linebreaks }}
{% for greeting in greetings %}
{% if greeting.author %}
{{ greeting.author.nickname }} wrote:
{% else %}
An anonymous person wrote:
{% endif %}
{{ greeting.content|escape }}
{% endfor %}
pyS60 gsm_location()
import location
print location.gsm_location()
เลข 4 ตัวมีความหมายดังนี้
- MCC Mobile Country Code
- MNC Mobile Network Code
MCC กับ MNC ใช้คู่กัน ดูตามตารางใน wiki
เช่น MCC=520 คือประเทศไทย MNC= 99 พอจับคู่กันก็เป็น True Move
| 520 | 99 | True Move | Operational | GSM 1800 |
- LAC Location Area Code
- CellID or CID Base Station Identity
ref : http://discussion.forum.nokia.com/forum/archive/index.php/t-54906.html