Posts Tagged 'SOA'



Service Bus 12c– Two way SSL

In this post, we will see how to enable two-way SSL in Service Bus 12c. The steps mentioned here have to be performed in addition to steps mentioned in the previous post.

Navigate to Servers –> osb_server1 –> SSL in WLS Admin Console. Expand Advanced section and set Two Way Client Cert Behavior as shown below. This would enforce WLS to request the Client certificate during SSL handshake and will result into an error if the client certificate is not present in trust store.

2ssl

Now create a keystore clientkeystore1.jks using following command and will  be used in SOAP UI.

keytool -genkeypair -keyalg RSA -alias localclient1 -keystore clientkeystore1.jks -storepass cljks123 -validity 360 -keysize 2048

Set global SSL Settings in SOAP UI as shown below by navigating to File –> Preferences. Specify the above created keystore and  password.

soapui

Restart OSB managed server. Now if you test your Proxy Service from SOAP UI, you would see an error like below in the server log as the trust store does not have the client certificate.

sslerror

So export and import corresponding Client Certificate into the OSB trust store using following commands.

keytool -exportcert -alias localclient1 -keystore clientkeystore1.jks -file localclient1.cer

keytool -importcert -alias localclient1 -keystore osbkeystore.jks -file localclient1.cer

clientstore

Now test your Proxy Service from SOAP UI and you would see the response as expected without any error. And now the server log will be shown like below.

sslsuccess

Please note that above logs are generated when following JVM options are set in setDomainEnv.cmd file for EXTRA_JAVA_PROPERTIES.

           -Dssl.debug=true -Dweblogic.StdoutDebugEnabled=true

Service Bus 12c– One way SSL

In this post, we will see how to configure Service Bus to use One way SSL.

Here, we are not discussing about the SSL concepts and people who want to go through quick introduction of SSL can go through this.

In Summary, following are the steps to be followed:

  • Generate Custom Identity and Trust stores.
  • Enable SSL port.
  • Setting up the keystores.
  • Configure private keys for SSL

Please note that, JSSE (Java Secure Socket Extension)  is the only supported SSL implementation. The Certicom-based SSL implementation is removed and is no longer supported in WebLogic Server.

Create a folder keystores %FMW_HOME% to store all of your keystores used and issue the following command to generate a keystore for Admin server use as shown below.

keytool -genkeypair -keyalg RSA -alias localadmin -keystore adminkeystore.jks -storepass adjks123 -validity 360 -keysize 2048

createks

This creates keystore adminkeystore.jks having both public and the private keys with alias localadmin. You can observe the contents of keystore using the following command.

keytool -list -v -keystore adminkeystore.jks

jkscontents

Similarly, create other keystores to use for OSB and SOA managed servers and also a keystore to use for the client as shown below.

keystores

Enable SSL port by navigating to Environment –> Severs-> Admin Sever –> General.

sslenable

By Default, WLS uses the Demo Identity and Trust keystores and you can find them in %DOMAIN_HOME/security and %WLS_HOME%/server/lib. Oracle strictly recommends to use the Custom keystores at least for the Production environments. Hence we will use the custom keystores in this post.

Go to Keystores tab and click Change.

demoks

Select Custom Identity and Custom  Trust as shown below and click Save.

customks

Modify Custom Identity and Trust stores as shown below and here you also need to give keystore password. Click Save.

customks1

Go to SSL tab and give the Private key alias as shown below.

sslsetup

Go to Advanced settings and set Hostname verification to None and also set Two way Client Cert Behavior to Clients Certs not Required as we are doing setup for 1-way SSL. This setting will enforce WLS server not to request client certificates.

sslsetup1

Modify EXTRA_JAVA_PROPERTIES  in setDomainEnv.cmd to use following parameters and restart the admin server. This is required as to instruct WLS server to load trusted certificates.

-Dweblogic.security.SSL.trustedCAkeystore=C:\Oracle\Middleware\FMW1213New \keystores\adminkeystore.jks -Djavax.net.ssl.trustStorePassword=adjks123

Now you should be able to access WLS admin console using following URL and this confirm the SSL is configured on your admin server.

http://localhost:7002/console

You can refer to WLS documentation here for more information on this.

The following error is observed when we use a keystore as Trust store with zero trust certificates.

<[Thread[DynamicJSSEListenThread[DefaultSecure3]],9,WebLogicServer]weblogic.security.SSL.jsseadapter: TRUSTSTORE_MANAGER: No certs to
copy.>
<[Thread[DynamicJSSEListenThread[DefaultSecure3]],9,WebLogicServer]weblogic.security.SSL.jsseadapter: TRUSTSTORE_MANAGER: No trusted
CAs available to populate trust anchors.>
<[Thread[DynamicJSSEListenThread[DefaultSecure3]],9,WebLogicServer]weblogic.security.SSL.jsseadapter: TRUSTSTORE_MANAGER: Error initi
alizing trust manager factory: the trustAnchors parameter must be non-empty.
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
at weblogic.security.SSL.jsseadapter.JaTrustManager.<init>(JaTrustManager.java:57)
at weblogic.security.SSL.jsseadapter.JaSSLContextImpl.initializeContext(JaSSLContextImpl.java:654)

To debug SSL, modify EXTRA_JAVA_PROPERTIES  in setDomainEnv.cmd to include the following parameters.

-Dssl.debug=true -Dweblogic.StdoutDebugEnabled=true

To enable javax.net debugging include the following parameter.

-Djavax.net.debug=all

To eliminate this error, you can install any trust certificate into localadmin.jks or use cacerts keystore (available in %WLS_HOME%/server/lib) as Trust store. Here i have exported Public Certificate from clientkeystore.jks and got that imported into localadmin.jks.

Use the following command to export:

            keytool -exportcert -alias localclient -keystore clientkeystore.jks -file localclient.cer

Use the following command to import:

             keytool -importcert -alias localclient -keystore adminkeystore.jks -file localclient.cer

Now verify the contents of your keystore as below.

              keytool -list -v -keystore adminkeystore.jks

localcer

Similarly, configure OSB managed server using keystore osbkeystore.jks and use 7005 as the SSL port. Restart the OSB server after your changes.

osbsslport

osbsslks

osbsslks1

To enable your proxy services to be accessed only by SSL, you have to enable HTTPS option as below.

osbsslps

Now if you try to access your Proxy Service WSDL from browser, it will be automatically uses SSL as shown below.

osbwsdl

Most of the people uses SOAP UI to test their webservices. If you try to access this WSDL, you will be able to access from SOAP UI even without adding the required certificates to trust store. This is because SOAP UI trusts all by default as per this forum post.

To confirm the enablement of SSL on the Proxy Service, let us try to create a Webservice Proxy in JDeveloper that prompts to accept/trust the certificate.

jdevcert

Observation:

When you enable SSL debugging, you might observe the following exception in server log though your 1-way SSL works as expected. As per Oracle Support note 1606295.1, this is not a harmful exception.

<1425221899641> <BEA-000000> <Exception processing certificates: peer not authenticated javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)
at weblogic.servlet.provider.WlsSecurityProvider.getSSLAttributes(WlsSecurityProvider.java:222)
at weblogic.servlet.internal.VirtualConnection.initSSLAttributes(VirtualConnection.java:165)
at weblogic.servlet.internal.VirtualConnection.init(VirtualConnection.java:75)
at weblogic.servlet.internal.ServletRequestImpl.initFromRequestParser(ServletRequestImpl.java:312)
at weblogic.servlet.internal.HttpConnectionHandler.dispatch(HttpConnectionHandler.java:577)
at weblogic.servlet.internal.MuxableSocketHTTP.dispatch(MuxableSocketHTTP.java:131)
at weblogic.socket.JSSEFilterImpl.dispatch(JSSEFilterImpl.java:216)
at weblogic.socket.MuxableSocketDiscriminator.dispatch(MuxableSocketDiscriminator.java:186)
at weblogic.socket.JSSEFilterImpl.dispatch(JSSEFilterImpl.java:216)
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:970)
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:907)
at weblogic.socket.NIOSocketMuxer.process(NIOSocketMuxer.java:495)
at weblogic.socket.NIOSocketMuxer.processSockets(NIOSocketMuxer.java:461)
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:30)
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:43)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:147)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:119)

SOA 12c – Using Maven for Service Bus deployment

In this post, we will see creation of Service Bus application and projects using maven archetypes. And we will use local Maven Repository for demonstration.

Generate Service Bus Application and Project as shown below.

mvn archetype:generate -DarchetypeGroupId=com.oracle.servicebus.archetype -DarchetypeArtifactId=oracle-servicebus-application -DarchetypeVersion=12.1.3-0-0 -DgroupId=org.my.test -DartifactId=test-servicebus-application -DprojectName=test-servicebus-project -Dversion=1.0-SNAPSHOT

Import this maven project in JDeveloper using the steps mentioned below. Select File –> Import and select Maven Project option and click OK.

import1

osbimport

osbappl

osbimported

Open application level POM file in Application Resources directory as shown below and observe the details.

osbapplpom

osbapplpom1

Open project level POM file and observe the details.

osbprojpom

Open System level POM file and observe the details.

osbsyspom

Add plugin and other server details in project level POM files (both System and Service Bus Project) as shown below. Remember using the Admin Server port as the server url.

<build>
<plugins>
<plugin>
<groupId>com.oracle.servicebus.plugin</groupId>
<artifactId>oracle-servicebus-plugin</artifactId>
<version>12.1.3-0-0</version>
<configuration>
<oracleServerUrl>
http://localhost:7001</oracleServerUrl>
<oracleUsername>weblogic</oracleUsername>
<oraclePassword>weblogic1</oraclePassword>
</configuration>
</plugin>
</plugins>
</build>

You can generate the sbar file for your Service Bus Projects using mvn package (from directory of Service Bus Application) and can be found in <<project>>/.data/ maven.

sbuspackage

Deploy your Service Bus projects using mvn pre-integration-test (from Service Bus application directory).

sbuspinttest

You can execute Service Bus Plugin goals in following manner from directory containing project POM file.

mvn com.oracle.servicebus.plugin:oracle-servicebus-plugin:package

mvn com.oracle.servicebus.plugin:oracle-servicebus-plugin:deploy**

You can observe goal prefix as servicebus, when you describe Service Bus Plugin as shown below.

osbgoalprefix

so you can execute all goals simply using this goal prefix as below.

mvn servicebus:package

mvn servicebus:deploy**

 

**Currently facing issue with deploy goal.

 

Notes:

  • Use double quotes in the maven commands like below if you are seeing the error mentioned in think link.

mvn install:install-file “-DpomFile=oracle-maven-sync-12.1.3.pom” “-Dfile=oracle-maven-sync-12.1.3.jar” “-DoracleHome=C:/Oracle/Middleware/FMW1213New”

  • Seems to be OSB maven functionality is broken in 12.2.1. Refer to following blog talking about this.

https://rhpatrickblog.wordpress.com/2015/11/11/restoring-osb-12-2-1-maven-functionality/

http://www.avioconsulting.com/blog/osb-12212-maven-fixes

SOA 12c – Using Maven for SOA deployment

In this post, we will see creation of SOA application/projects using the maven archetypes. And we will use local Maven Repository for the demonstration.

Navigate to %MW_HOME%\oracle_common\plugins\maven\com\oracle\maven\oracle-maven-sync\12.1.3 and use following commands to sync your local repository:

mvn install:install-file -Dfile=oracle-maven-sync-12.1.3.jar -DpomFile=oracle-maven-sync-12.1.3.pom

mvn com.oracle.maven:oracle-maven-sync:push -Doracle-maven-sync.oracleHome=%MW_HOME%

Update your archetype catalog using:

mvn archetype:crawl -Dcatalog=C:\Users\<<uname>>\.m2\archetype-catalog.xml

Generate SOA Application and project as shown below. This generates SOA application test-soa-application with  project test-soa-project.

mvn archetype:generate -DarchetypeGroupId=com.oracle.soa.archetype -DarchetypeArtifactId=oracle-soa-application -DarchetypeVersion=12.1.3-0-0 -DgroupId=org.my.test -DartifactId=test-soa-application -DprojectName=test-soa-project -Dversion=1.0-SNAPSHOT

Import this maven project in JDeveloper using File –> Import and select the Maven Project option as shown below. Click OK.

import1

Give your application directory as Root Directory which brings up all POMs and select other options as shown below. Click OK.

importmaven

Enter Application Name and click OK.

importappl

Click OK if you get any error related to overriding the existing project dialog so that jws file is created. Now your project explorer should look like as below.

importedprj

Open application level POM file in Application Resources directory as shown below and observe the details.

applpom1

applpom

Open project level POM file in Resources directory of SOA Project and observe the details.

projpom

Compile SOA Application using mvn compile (from directory of SOA Application).

compile

Modify server details in project level POM file as shown below and deploy your SOA projects using mvn pre-integration-test (from SOA application directory).

compilechng

After execution, you will see following output and also can observe the SOA project deployed to SOA server as shown below.

preintg

deployed

You can execute SOA Plugin goals in the following manner from the directory containing project POM file.

mvn com.oracle.soa.plugin:oracle-soa-plugin:compile

mvn com.oracle.soa.plugin:oracle-soa-plugin:sar

mvn com.oracle.soa.plugin:oracle-soa-plugin:deploy

mvn com.oracle.soa.plugin:oracle-soa-plugin:undeploy

You can observe goal prefix as oracle-soa, when you describe the SOA Plugin as shown below.

soagolaprefix

so you can execute all goals simply using this goal prefix as below.

mvn oracle-soa:compile

mvn oracle-soa:sar

mvn oracle-soa:deploy

mvn oracle-soa:undeploy

 

Note: Use double quotes in the maven commands like below if you are seeing the error mentioned in this link.

mvn install:install-file “-DpomFile=oracle-maven-sync-12.1.3.pom” “-Dfile=oracle-maven-sync-12.1.3.jar” “-DoracleHome=C:/Oracle/Middleware/FMW1213New”

SOA 12c – Using Maven Sync Plugin

Oracle recently released Maven Repository which is a giant leap in adopting Maven too for building, packaging and deploying SOA, ADF applications. You can access the repository here. To access this, you should be registered user with Oracle and accept the licensing terms.

In this post, we will see how to setup Archiva repositories and populate it with artifacts from Oracle Home. You can refer to Oracle FMW Continuous Integration documentation here for more information.

You can download the latest version of Archiva from here and corresponding documentation can be found here.

Archiva installation is so simple and you have to just unzip file contents. The standalone distribution comes up with bundled jetty server. By default, the server uses port 8000. You can always change this port to your desired value as shown below by modifying jetty.xml in conf directory.

serverport

Navigate to bin directory and start the server using the following command:

archiva console

serverstart

Once the server started, launch archiva using url http://localhost:8088. The first step is to create the admin user as shown below, so CreateAdmin User on the page launched. Enter the password and email and do Save.

admin

Now login using Admin credentials and navigate to Repositories which shows 2 default repositories as shown below.

defaultrepo

By default, the internal repository is for maintaining the fixed-version released artifacts includes finished versions of artifacts, versions that are no longer in development, and released versions. And the snapshot repository holds the work-in-progress artifacts denoted with a version having suffix SNAPSHOT, and artifacts that have not yet been released.

Here, we will create repositories keeping development environment in mind. It’s always recommended to create different repositories for DEV, QA and PROD as there is possibility of having different versions of same artifacts. For our purpose, we will reuse the snapshots repository and create 2 repositories mirror and dev. The mirror repository is used to cache third-party proxied artifacts and dev is used similar as internal repository.

Navigate to Repositories link and click Add. Set the properties similar to below.

mirrow

Click Save to go back to Managed Repositories page as shown below and here you can observe the new mirror repository.

repolistaftermirror

Create dev repository in similar way and make sure that you uncheck Block Redeployments as shown below.

devrepo

devlist

Archiva has a provision to create  Repository Groups, that allows to specify single URL instead of multiple repository URLs when we are using more than 1 repository.

Here we will create a repository group dev-group consisting of all the above. Navigate to Repository Groups and click Add.

repogrp

Give the name as dev-group and drag dev, snapshots and mirror repositories from Available list to left as shown below.

devgroup1

devgroup2

Click Save and observe the repository group as shown below.

repogrplist

Archiva uses proxy connector to link local repository with a remote repository. So when a request is received by repository, the connector decides whether it should request artifact from remote repository and cache the result locally for future requests.

By default, internal repository is connected to remote repository using Proxy Connector. This you can observe by navigating to Proxy Connectors as shown below.

pconndel

Since we want our mirror repository to proxy remote repository, delete the existing proxy connector. Click Add and create new Proxy Connector as shown below. Observe that Managed Repository is selected as mirror. Click Save.

pconncreate

With this, you have finished setting up required Archiva repositories.

By default, Oracle FMW installation comes up with Maven 3.0.5 and is available in following location. So set M2 and M2_HOME system variables accordingly.

%MW_HOME%\oracle_common\modules\org.apache.maven_3.0.5

Using Oracle Maven Sync Plugin

Navigate to the directory %MW_HOME%\oracle_common\plugins\maven\ com\oracle\ maven\oracle-maven-sync\12.1.3.

Install plugin:

mvn install:install-file -Dfile=oracle-maven-sync-12.1.3.jar -DpomFile=oracle-maven-sync-12.1.3.pom

 

Use the following as your user specific maven settings. Remember to modify the passwords in server elements.

 

Deploy plugin to dev Repository:

mvn deploy:deploy-file -Dfile=oracle-maven-sync-12.1.3.jar -DpomFile=oracle-maven-sync-12.1.3.pom  -Durl=http://localhost:8088/repository/dev  -DrepositoryId=dev

mavensync

Verifying Sync plugin:

mvn help:describe -Dplugin=com.oracle.maven:oracle-maven-sync –Ddetail

mvnsynchelp

Do the Sync:

mvn com.oracle.maven:oracle-maven-sync:push -DoracleHome=%MW_HOME% -DserverId=dev

You can verify the synced artifacts in dev repository as shown below

installed

Verifying SOA plugin

mvn help:describe -DgroupId=com.oracle.soa.plugin -DartifactId=oracle-soa-plugin -Dversion=12.1.3-0-0

soaplugin

Verifying Service Bus plugin

mvn help:describe -DgroupId=com.oracle.servicebus.plugin -DartifactId=oracle-servicebus-plugin -Dversion=12.1.3-0-0

sbusplugin

Note: Use double quotes in the maven commands like below if you are seeing the error mentioned in this link.

mvn install:install-file “-DpomFile=oracle-maven-sync-12.1.3.pom” “-Dfile=oracle-maven-sync-12.1.3.jar” “-DoracleHome=C:/Oracle/Middleware/FMW1213New”

SOA 12c–EDN with Service Bus

In this post, I just want to present an idea on how to make Service Bus work with EDN in SOA Suite 12c. For demonstration purpose, I will consider Durable Subscriber functionality introduced in 12c.

You can download the SOA and Service Bus projects here and here.

My setup includes 2 business events Create Order and Update Order and have the following durable subscribers created because of SOA Composites. Refer to these articles for more information on EDN. Note that, Client ID is different as mentioned below based on the consistency level used for the event subscription.

       For Guaranteed   -> edn_wljsm_localtx_client

       For OneandOnlyOne   -> edn_wljsm_xa_client

Main idea is to create a durable subscriber for our Proxy Service similar to the ones shown below. So note down Client ID and Message Selector shown below and use it in our Proxy Service configuration. Here we are subscribing our Proxy Service to Create Order business event.

soasubscr1

soasubscrmsgslet

Now create Proxy Service and set Endpoint URI in Transport tab as shown below. EDN uses EDN Topic for storing and delivering the EDN messages to subscribers.

topicps1

Give the Message Selector and Client ID noted in previous step in Transport Details tab as shown below and select Durable Subscription option.

topicps2

Deploy you Service Bus project and observe that another durable subscriber has been created for Proxy Service as shown below.

osbdura1

To make sure that things are working as expected, push the message read by Proxy service to other JMS queue. Here I created queue named CustomJmsQ and following screenshot shows no messages are pushed yet.

customqmsg

Raise the Create Order business event from SOA Composite. And you can observe that message payload have been inserted into JMS queue.

custommsgaftrtest

evntpayloadjms

Shut down OSB managed server and observe status of  durable subscriber. As shown below the Active status is shown as false indicating that Proxy service is not longer ready to accept messages.

osbinactive

Again raise the Create Order business event. And now you can observe that message is shown in Current Count means not yet delivered to Proxy Service.

pendingmsg

pendingmsg1

Now restart your OSB managed server navigate to CustomJmsQ. Now you can observe 2 messages in this queue including the latest one as shown below.

osbsrvrrestart1

osbsrvrrestart2

Now Un-deploy Service Bus project. And you can observe that corresponding durable subscriber is deleted too.

Remember the following:

  • EDN bus comes with SOA server, so you may not be able to use EDN in OSB only deployments.
  • Since there is no native support for business events in service bus, we will not be able to set any consistency levels and even the retry would not happen similar to SOA composites.
  • Here we directly gave Endpoint URI of Proxy Service to point to EDNTopic residing different server. Ideally, you may have to go for foreign server.
  • Finally, I have not verified the same with client edn_wlsjms_xa_client. Please let me know in comments when you try.

SOA 12c – EDN – Mapping to Custom Topic with AQJMS

We have seen using Custom Topic with WeblogicJMS here and in this post we will see the same using AQJMS.

Creating a new Topic

Run the following script to create new AQ Topic.

define edn_user=dev12c_soainfra
define topic=EDN_AQJMS_CUST_TOPIC
define topic_table=EDN_AQJMS_CUST_TOPIC_TBL

 
begin
  DBMS_AQADM.stop_queue(queue_name => ‘&edn_user..&topic’);
  DBMS_AQADM.drop_queue(queue_name => ‘&edn_user..&topic’);
  DBMS_AQADM.drop_queue_table(queue_table => ‘&edn_user..&topic_table’);
end;
/
begin
  dbms_aqadm.create_queue_table(queue_table => ‘&edn_user..&topic_table’,
                                queue_payload_type => ‘SYS.AQ$_JMS_MESSAGE’,
                                multiple_consumers => true);
  dbms_aqadm.create_queue(queue_name => ‘&edn_user..&topic’,
                          queue_table => ‘&edn_user..&topic_table’,
                          max_retries => 256);
  dbms_aqadm.start_queue(queue_name        =>       ‘&edn_user..&topic’);
end;
/
commit;

Once script is run successfully, verify that AQ Topic and corresponding Queue Table is created as shown below.

aqcusttopic

You can also observe other tables created when you create a new topic.

aqtopictables

Now create a foreign destination in  foreign server EDNAQjmsForeignServer. So navigate to Services –> Messaging –> JMS Modules –> SoaJMSModule –> EDNAQjmsForeignServer –> Configuration –> Destinations in Weblogic Administration console and create as shown below:

aqcust1

Enter a meaningful name and Local JNDI for the topic. And the remote JNDI should be of the format Topics/<<AQ Topic Name>> as shown below.

aqcust2

Click OK and observe the new foreign destination created as shown below.

aqcust3

Modifying Business Event mapping

Navigate to SOA –> soa-infra –> SOA Infrastructure –> Business Events in EM and click JMS Mapping as shown below.

aqmapping

Modify JMS Topic Name to use newly created Topic and click Apply. Typically, you don’t have to create new Connection Factories. Restart the affected composites so that modified JMS mapping will be effective.

For demonstration purpose, here we are modifying the JMS Mapping for CreateOrder Business Event.

aqmodmapping

Raise CreateOrder Business Event and observe log (with OneandOnlyOne consistency level).

[2015-01-12T20:16:20.544+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ’21’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 5c9ca2bf-9639-4e37-a951-cb3b9fb7c06c-00000123,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 20002] [oracle.soa.tracking.InstanceId: 20004] [oracle.soa.tracking.SCAEntityId: 29] [composite_name: EDNConsistencyCheck] [FlowId: 0000KfUb1lY3z0WjLxyGOA1Kgxik000002] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaDurableTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Starting JCA LocalTransaction
[2015-01-12T20:16:20.545+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ’21’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 5c9ca2bf-9639-4e37-a951-cb3b9fb7c06c-00000123,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 20002] [oracle.soa.tracking.InstanceId: 20004] [oracle.soa.tracking.SCAEntityId: 29] [composite_name: EDNConsistencyCheck] [FlowId: 0000KfUb1lY3z0WjLxyGOA1Kgxik000002] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaDurableTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Invoking JCA Outbound Interaction
[2015-01-12T20:16:21.913+05:30] [soa_server1] [NOTIFICATION] [] [oracle.soa.adapter.jms.outbound] [tid: [ACTIVE].ExecuteThread: ’21’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 5c9ca2bf-9639-4e37-a951-cb3b9fb7c06c-00000123,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 20002] [oracle.soa.tracking.InstanceId: 20004] [oracle.soa.tracking.SCAEntityId: 29] [composite_name: EDNConsistencyCheck] [FlowId: 0000KfUb1lY3z0WjLxyGOA1Kgxik000002] JMSMessageProducer_produce: Successfully produced message with ID ID:11F4B4F68C6A4B93B6BAB1305CA03C72 to destination jms/fabric/EDNAQjmsCustTopic
[2015-01-12T20:16:21.913+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ’21’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 5c9ca2bf-9639-4e37-a951-cb3b9fb7c06c-00000123,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 20002] [oracle.soa.tracking.InstanceId: 20004] [oracle.soa.tracking.SCAEntityId: 29] [composite_name: EDNConsistencyCheck] [FlowId: 0000KfUb1lY3z0WjLxyGOA1Kgxik000002] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaDurableTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Committing JCA LocalTransaction

In above log, you can clearly observe that Business Event is published in our topic jms/fabric/EDNAQjmsCustTopic and default connection factory is used. You can refer to my previous post on how to generate this EDN log, if required.

You can also try with Guaranteed consistency level and can observe that the connection factory eis/aqjms/EDNLocalTxDurableTopic has been used along with new Topic we created.

SOA 12c – EDN Articles

Following bugs related to EDN have been fixed in the patch bundle (12.1.3.0.1). For the complete list of fixed bugs, one can refer to README of the patch bundle 19707784.

18860738: BACKLOG EVENTS LOST WHEN NEW REVISION OF EDN SUBSCRIBERS DEPLOYED
18632135: UPGRADE OF EDN-JMS BACKLOG EVENTS FROM 11G TO 12C
18710784: INCORRECT STATE FOR EDN SUBSCRIBER AFTER UPGRADE EDNJMSMODE=TRUE

SOA 12c – EDN – Durable Subscribers with AQ JMS

In this post, we will see how Durable Subscribers work when using AQJMS. It’s advised to have a look at previous post to understand on how to switch to AQJMS from default Weblogic JMS.

We will use the following Business Events for demonstration purpose where CreateOrder event has 3 subscriptions and UpdateOrder has 1 subscription and Durable property is set to Yes.

duraaq1

From JMS Mapping shown below, you can find out the JNDI of JMS topic which is jms/fabric/EDNAQjmsTopic.

duraaq2

In WLS Admin Console, navigate to Services –> Messaging –> JMS Modules –> SOAJMSModule –> EDNAQjmsForeignServer –> Destinations and observe Remote JNDI of corresponding JNDI of JMS topic observed in above step. From this, actual AQ topic used by EDN is EDN_AQJMS_TOPIC.

duraaq3

You can observe AQ Topic and corresponding DB table used by EDN to store messages as shown below. Remember to connect to DB using SOAINFRA schema credentials.

duraaqtable

In addition to queue table, following are other DB tables used by EDN and will be created automatically as part of SOAINRA schema creation or when you create any custom AQ topic.

duraaqtable1

Following information is an extract from this documentation and presenting for your quick reference here.

Table name

Description

AQ$_queue_table_name_D Table for storing information about propagations and apply processes that are eligible for processing each event.
AQ$_queue_table_name_E Default exception queue associated with the queue table.
AQ$_queue_table_name_H An index organized table (IOT) for storing dequeue history data.
AQ$_queue_table_name_I An index-organized table (IOT) in the case of multiple consumer queues for dequeue operations.
AQ$_queue_table_name_L Dequeue log table, used for storing message identifiers of committed dequeue operations on the queue.
AQ$_queue_table_name_P Table for storing the captured events that spill from memory.
AQ$_queue_table_name_S A table for storing information about subscribers.
AQ$_queue_table_name_T An index for the queue monitor operations

We will discuss about the important tables below from this list.

AQ$_EDN_AQJMS_TOPIC_TABLE_S

You can query this table to find the Durable subscribers as shown below.

durasubscr

You can also get information about these subscribers in following way.

subscr1

Click on Subscribers. You can observe Consumer Name, Delivery Mode and whether it’s Durable subscriber or not.

subscr

subscr2

EDN_AQJMS_TOPIC_TABLE

This is queue table associated with our AQ and you can observe the messages in this table when you raise a business event. You can also get MSGID from EDN log (refer to this post on how to generate EDN logs).

Following screenshot shows the message created when CreateOrder event is raised.

duramsg1

You can also see event payload  in USER_DATA column as shown below.

duramsg2

AQ$_EDN_AQJMS_TOPIC_TABLE_H

This table contains de-queue history for each of subscribers of an event. The following screenshot shows messages for 3 subscribers of CreateOrder event (observe subscriber# column below).

duramsg3

AQ$_EDN_AQJMS_TOPIC_TABLE_I

This table contains messages meant for de-queue operations for each of subscribers of an event. This we can observe clearly when any of the durable subscribers are down, which we will see later.

It has been observed that the messages are being purged automatically from the above tables, once all subscribers have received the event and successfully processed it.

If the business events are staged in buffer for a period of time without being de-queued, or if there is no enough space in memory to hold all of these captured events, then the tables AQ$_EDN_AQJMS_TOPIC_TABLE_P and AQ$_EDN_AQJMS_TOPIC_TABLE_D are used to store these spilled events.

Now we will observe how these subscribers get affected in the following scenarios:

  • Deployment of composites with Durable property to Yes.
  • Any of the Composites subscribed to business events are shutdown.
  • Redeployment of composites with same revision.
  • Redeployment of composites with different default revision. 
  • Un-deployment of the composites.
  • Redeployment of composites after modifying Durable property to No.

Durable property to Yes:

We have already seen above that subscribers have been created as expected where Subscriber/Consumer name has corresponding Business Event name.

Subscribers Down:

Shutdown one of the composites subscribing to CreateOrder business event. In this case you can observe the records in all of the above tables that we discussed as all subscribers have not processed the event.

durasubscr

EDN_AQJMS_TOPIC_TABLE

subscrdown

AQ$_EDN_AQJMS_TOPIC_TABLE_I

This table shows only one message corresponding to inactive subscriber.

subscrdown1

AQ$_EDN_AQJMS_TOPIC_TABLE_H

This table clearly shows that 2 of the messages related to active subscribers have been de-queued along with de-queue time and one more message is yet to be de=queued as the subscriber is down.

subscrdown2

AQ$_EDN_AQJMS_TOPIC_TABLE_F

This table also shows only one message corresponding to inactive subscriber along with other information present in EDN_AQJMS_TOPIC_TABLE.

subscrdown3

Now bring up the composite and query all of the above tables and you will find them empty as the message is delivered as expected.

Redeployment of Composites:

Redeployment of some composites with same revision resulted into recreation of Durable Subscribers and older ones are either completely deleted or just updated with Deletion Time but Subscriber/ Consumer name is never changed as shown below. Also Subscriber Type is set to 2 denoting UNDELIVERABLE.

subscr3

Same is the case when composites are redeployed with different revision but now Subscriber/Consumer name is also modified as shown below.

subscr4

Un-deployment of Composites:

Un-deployment of composites also resulted into either deletion of entries or Deletion Time and Subscriber Type is updated as described in previous scenario. But could not conclude on why 2 different behaviors exist.

Durable property to No:

Subscribers have been created as expected but Subscriber/Consumer name are set differently as shown below.

durableno

durableno1

Let us bring down the composite down once again to see how it’s affected the subscriber. From the below screenshot, you can observe that corresponding subscribers are marked with Deletion time and Subscriber type is set to 2 means undeliverable.

durableno3

Other Observations:

  • Subscriber Type is 193 in table aq$_edn_aqjms_topic_table_S when subscriber is active and value 2 denotes undeliverable.
  • The message assumes the following states during it’s lifecycle and the column state in table edn_aqjms_topic_table denotes this. These value are derived from definition of DB view AQ$EDN_AQJMS_TOPIC_TABLE.

State

Meaning

0 Ready
1 Wait
2 Processed
3 Expired
8 Deferred
10 Buffered Expired
  • When any one of the composites throws an exception (considering the BPEL invocation is Sync), retry is happening thrice as expected and retry count is marked in aq$_edn_aqjms_topic_table_H as shown below.

        retry

        retry1

Note: Could not conclude the purpose of tables AQ$_EDN_AQJMS_TOPIC_TABLE_F and AQ$_EDN_AQJMS_TOPIC_TABLE_G and AQ$_EDN_AQJMS_TOPIC_TABLE_T . If anybody is aware of the functionality, one can let me know through your comments. And the table AQ$_EDN_AQJMS_TOPIC_TABLE_L showing log only during events delivery and is getting cleared once all events have been processed successfully.

SOA 12c – EDN –Using AQ JMS

In this post, We will see how to use AQJMS with EDN in SOA Suite 12c (Weblogic JMS is the default mechanism).

Navigate to Weblogic Domain –> <<your domain>> –> System MBean Browser –> oracle.as.soainfra.config –> <<SOA server>> –> EDNConfig-> edn. Modify JMS type to AQJMS as shown below.

aq1

This change will reflect in Business Events screen as shown below. You can observe JMS Type is shown as Oracle Advanced Queueing for UpdateOrder business event.

aq2

Clicking on JMS Mapping shows the default Connection Factories and Topic used. You can observe that JMS mapping is changed to use respective AQ resources.

aq3

After this change, restart the affected composites and publish Update Order business event to verify the generated log. Below, you can clearly observe that AQ Connection factory EDNxaTopic and AQ Topic EDNAQjmsTopic has been used. This log is generated when Update Order event consistency level is set to OneandOnlyOne and Durable property set to No.

[2014-12-27T21:35:49.171+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ‘5’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 368b87b8-a4fd-407a-855e-5e3d83be4c13-00000a99,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 40010] [oracle.soa.tracking.InstanceId: 40024] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeCVlz^3z0WjLxyGOA1KbOd000000A] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Starting JCA LocalTransaction
[2014-12-27T21:35:49.171+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ‘5’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 368b87b8-a4fd-407a-855e-5e3d83be4c13-00000a99,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 40010] [oracle.soa.tracking.InstanceId: 40024] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeCVlz^3z0WjLxyGOA1KbOd000000A] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Invoking JCA Outbound Interaction
[2014-12-27T21:35:49.184+05:30] [soa_server1] [NOTIFICATION] [] [oracle.soa.adapter.jms.outbound] [tid: [ACTIVE].ExecuteThread: ‘5’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 368b87b8-a4fd-407a-855e-5e3d83be4c13-00000a99,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 40010] [oracle.soa.tracking.InstanceId: 40024] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeCVlz^3z0WjLxyGOA1KbOd000000A] JMSMessageProducer_produce: Successfully produced message with ID ID:AE8CF801AB594F6AA535BE5FB2654FC8 to destination jms/fabric/EDNAQjmsTopic
[2014-12-27T21:35:49.185+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ‘5’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: 368b87b8-a4fd-407a-855e-5e3d83be4c13-00000a99,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 40010] [oracle.soa.tracking.InstanceId: 40024] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeCVlz^3z0WjLxyGOA1KbOd000000A] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Committing JCA LocalTransaction.

Resources used by AQJMS for EDN

Consistency Level

Durable

Connection Factory (JNDI)

AQ Topic (JNDI)

OneandOnlyOne Yes eis/aqjms/EDNxaDurableTopic jms/fabric/EDNAQjmsTopic
OneandOnlyOne No eis/aqjms/EDNxaTopic jms/fabric/EDNAQjmsTopic
Guaranteed Yes eis/aqjms/EDNLocalTxDurableTopic jms/fabric/EDNAQjmsTopic
Guaranteed No eis/aqjms/EDNLocalTxTopic jms/fabric/EDNAQjmsTopic

Foreign Servers:

EDNAQjmsForeignServer

EDNAQjmsLocalTxForeignServer

Data Sources:

jdbc/EDNDataSource

jdbc/EDNLocalTxDataSource

Actual AQ Topic:

EDN_AQJMS_TOPIC

Remember the change of JMS type does not apply to Business Events where JMS mapping is done with a Custom Topic. For example, here Create Order Business Event is using Custom topic so JMS type is retained as Weblogic JMS even after modification in MBean.

aq4nochange

aq5nochange

With Durable set to Yes

Following is log generated when Durable property is set to Yes for Update Order Business Event. Here, can clearly observe that corresponding Durable Connection factory has been used and the same AQ Topic. Similarly you can try and verify log for Guaranteed consistency level with Durable property Yes/No.

[2014-12-30T22:54:27.420+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ’20’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: a9de2c34-beec-4e15-93d1-cee78dc3dc4e-000002c4,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 60003] [oracle.soa.tracking.InstanceId: 60007] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeSEZAD3z0WjLxyGOA1Kcgt9000004] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaDurableTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Starting JCA LocalTransaction
[2014-12-30T22:54:27.421+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ’20’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: a9de2c34-beec-4e15-93d1-cee78dc3dc4e-000002c4,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 60003] [oracle.soa.tracking.InstanceId: 60007] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeSEZAD3z0WjLxyGOA1Kcgt9000004] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaDurableTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Invoking JCA Outbound Interaction
[2014-12-30T22:54:27.628+05:30] [soa_server1] [NOTIFICATION] [] [oracle.soa.adapter.jms.outbound] [tid: [ACTIVE].ExecuteThread: ’20’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: a9de2c34-beec-4e15-93d1-cee78dc3dc4e-000002c4,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 60003] [oracle.soa.tracking.InstanceId: 60007] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeSEZAD3z0WjLxyGOA1Kcgt9000004] JMSMessageProducer_produce: Successfully produced message with ID ID:B76D31728D484942A2DD718BD928F646 to destination jms/fabric/EDNAQjmsTopic
[2014-12-30T22:54:27.628+05:30] [soa_server1] [TRACE] [] [oracle.integration.platform.blocks.event.jms2.EdnBus12c] [tid: [ACTIVE].ExecuteThread: ’20’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: <anonymous>] [ecid: a9de2c34-beec-4e15-93d1-cee78dc3dc4e-000002c4,0:2] [APP: soa-infra] [J2EE_APP.name: soa-infra] [J2EE_MODULE.name: fabric] [WEBSERVICE.name: RaiseEvent_ep] [WEBSERVICE_PORT.name: execute_pt] [oracle.soa.tracking.FlowId: 60003] [oracle.soa.tracking.InstanceId: 60007] [oracle.soa.tracking.SCAEntityId: 11] [composite_name: EDNConsistencyCheck] [FlowId: 0000KeSEZAD3z0WjLxyGOA1Kcgt9000004] [SRC_CLASS: oracle.tip.adapter.fw.log.LogManagerImpl] [SRC_METHOD: log] eis/aqjms/EDNxaDurableTopic EdnBus12c file://wsdl/eis/aqjms/EDNxaDurableTopic-OUTBOUND.wsdl [ eis/aqjms/EDNxaDurableTopic-OUTBOUND::enqueue(part,part) ] – Committing JCA LocalTransaction


Pages

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 377 other followers

Enter your email address to follow this blog and receive notifications of new posts by email.