I'm trying to use Netflix Hystrix open source API in an existing project to handle fault tolerance and Circuit Breaker implementation. I have referred some websites, but I couldn't get complete information about the implementation.
How can i invoke the below Hystrix program from my service class and what object it returns i'm unable to understand.
Below is the sample program about Hystrix.
Can anybody please help me to do this.
public class CommandHelloWorld extends HystrixCommand<String> {
private final String name;
public CommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
#Override
protected String run() {
return "Hello " + name + "!";
}
public static class UnitTest {
#Test
public void testSynchronous() {
assertEquals("Hello World!", new CommandHelloWorld("World").execute());
assertEquals("Hello Bob!", new CommandHelloWorld("Bob").execute());
}
#Test
public void testAsynchronous1() throws Exception {
assertEquals("Hello World!", new CommandHelloWorld("World").queue().get());
assertEquals("Hello Bob!", new CommandHelloWorld("Bob").queue().get());
}
#Test
public void testAsynchronous2() throws Exception {
Future<String> fWorld = new CommandHelloWorld("World").queue();
Future<String> fBob = new CommandHelloWorld("Bob").queue();
assertEquals("Hello World!", fWorld.get());
assertEquals("Hello Bob!", fBob.get());
}
}
}
Related
I am trying to create a generic router whose processor and other attributes are populated from a static class. Here is sample code.
public class GenericRouter extends RouteBuilder( {
#Override
public void configure() throws Exception {
from("direct:generic-route")
.process(Util.getProcesss(“${exchangeProperty[processKey]"))
.ToD(Util.getUrl(“${exchangeProperty[urlKey]"));
}
}
Public class Util{
Map<String,Object> routerResources;
static {
//load routerResources
}
public static Processor getProcessor(String processorKey){
return (Processor)routerResources.get(processorKey);
}
public static Processor getUrl(String urlKey){
return (String)routerResources.get(urlKey);
}
}
The generic router is expected to post a rest call. the properties "urlKey" and "processorUrl" are already available in exchange. I finding it difficult to pass exchange properties to static Util class methods.
If you want to access properties of an exchange in plain java you can use .process or .exchange. If you need to access body or headers you can use e.getMessage().getBody() and e.getMessage().getHeader()
from("direct:generic-route")
.process( e -> {
String processKey = e.getProperty("processKey", String.class);
Processor processor = Util.getProcessor(processKey);
processor.process(e);
})
.setProperty("targetURL").exchange( e -> {
String urlKey = e.getProperty("urlKey", String.class);
return Util.getUrl(urlKey);
})
.toD("${exchangeProperty.targetURL}");
Also make sure you fix the return type of this method:
public static Processor getUrl(String urlKey){
return (String)routerResources.get(urlKey);
}
As a side note, you can actually use map stored in body, header or property through simple language.
public class ExampleTest extends CamelTestSupport {
#Test
public void example(){
template.sendBodyAndHeader("direct:example", null, "urlKey", "urlA");
}
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
Map<String, String> urlMap = new HashMap<>();
urlMap.put("urlA", "direct:pointA");
urlMap.put("urlB", "direct:pointB");
from("direct:example")
.setProperty("urlMap").constant(urlMap)
.log("url: ${exchangeProperty.urlMap['${headers.urlKey}']}");
}
};
}
}
It wouldbe silly question but would be great help it you can help me out.
I tried implementing extent report for multple test cases, but report are not getting generated .
Code:
public class SampleTc1
{
static WebDriver driver;
static ExtentReports report;
static ExtentTest logger;
static void testcase1()
{
System.setProperty("webdriver.chrome.driver","chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://www.google.co.in");
logger.log(LogStatus.PASS, "This step is passed");
driver.close();
}
}
public class SampleTc2
{
static WebDriver driver;
static ExtentReports report;
static ExtentTest logger;
static void testcase2()
{
System.setProperty("webdriver.chrome.driver","chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://www.google.co.in");
logger.log(LogStatus.PASS, "This step is passed");
driver.close();
}
}
Main Class:
public class Maindriver {
static WebDriver driver;
static ExtentReports report;
static ExtentTest logger;
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
report=new ExtentReports("./Report/ExtentReport/ExecutionResult.html", true);
logger=report.startTest("TC1", "Testc Case1");
SampleTc1.testcase1();
report.endTest(logger);
logger=report.startTest("TC2", "Testc Case2");
SampleTc2.testcase2();
report.endTest(logger);
report.flush();
}
}
After running no reports are getting generated and it is showing null ponter exception:
Exception in thread "main" java.lang.NullPointerException
at SmokeTest.SampleTc1.testcase1(SampleTc1.java:24)
at SmokeTest.Maindriver.main(Maindriver.java:22)
Above exception I am getting.
Thanks in advance.
If you are using testng for running selenium suite, you can implement extent reports as a listener.
Like,
public class ExtentReporterNG implements IReporter
{
public ExtentReports extent;
private void buildTestNodes(IResultMap testMap, LogStatus status)
{
ExtentTest test;
if (testMap.size() > 0)
{
for (ITestResult result : testMap.getAllResults())
{
//test = extent.startTest(result.getInstance().getClass().getSimpleName(),result.getMethod().getMethodName());
test = extent.startTest(result.getMethod().getMethodName().toUpperCase(),result.getInstance().getClass().getSimpleName().toUpperCase());
test.assignCategory(result.getInstance().getClass().getSimpleName().toUpperCase());
test.setStartedTime(getTime(result.getStartMillis()));
for (String group : result.getMethod().getGroups())
test.assignCategory(group);
String message = "Test " + status.toString().toLowerCase() + "ed";
if (result.getThrowable() != null)
message = result.getThrowable().getMessage();
test.setEndedTime(getTime(result.getEndMillis()));
test.log(status, message);
extent.endTest(test);
}
}
}
private Date getTime(long millis)
{
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(millis);
return calendar.getTime();
}
#Override
public void generateReport(List<XmlSuite> xmlsuite, List<ISuite> suites,String file)
{
final String filePath=GlobalSettings.getProperty(GlobalSettings.EXTENTFILE);
extent = new ExtentReports(filePath, true,DisplayOrder.NEWEST_FIRST,NetworkMode.OFFLINE );
extent.loadConfig(new File("./config/extentConfig.xml"));
for (ISuite suite : suites)
{
Map<String, ISuiteResult> result = suite.getResults();
for (ISuiteResult r : result.values())
{
ITestContext context = r.getTestContext();
buildTestNodes(context.getPassedTests(), LogStatus.PASS);
buildTestNodes(context.getFailedTests(), LogStatus.FAIL);
buildTestNodes(context.getSkippedTests(), LogStatus.SKIP);
buildTestNodes(context.getFailedConfigurations(),LogStatus.FAIL);
buildTestNodes(context.getSkippedConfigurations(),LogStatus.SKIP);
}
}
extent.flush();
extent.close();
}}
It is not well organized, hard to say what/where is the problem ...
You can check here a selenium webdriver testng tutorial I used it when I started and it is a good starting point!
You have to change your ExtentReports as static in the base class. I got this idea from Mukesh Otwani, Selenium automation trainer for Learn-Automation.
I created separate class for extent report, hence avoided NULL pointer exception
Before I setup a test class like the code below:
1. the Factory and test Dataprovider both used excel as the dataprovider.
2. In the Factory dataprovider table, it has a list of url
3. Each time, it will find one of the url in the factory dataprovider table, and run the test in each test methods..
public class Test {
WebDriver driver;
private String hostName;
private String url;
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url) {
this.hostName = hostName;
this.url = url;
}
#BeforeMethod
#Parameters("browser")
public void start(String browser) throws Exception {
driver = new FirefoxDriver();
driver.get(url);
Thread.sleep(1000);
}
#Test(priority = 10, dataProvider = "dataprovider Test A", dataProviderClass = xxx.class)
public void TestA(Variable1,
Variable2,Variable3) throws Exception {
some test here...
}
#Test(priority = 20, dataProvider = "dataprovider Test B", dataProviderClass = xxx.class)
public void TestB(Variable1,
Variable2,Variable3)
throws Exception {
some test here...
}
#AfterMethod
public void tearDown() {
driver.quit();
}
Now I want to dynamically assign different group for each test for different url. I am thinking add a variable 'flag' in the #Factory dataprovider:
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url, String flag) {
this.hostName = hostName;
this.url = url;
this.flag = flag;
}
That when flag.equals("A"), it will only run test cases in test groups={"A"}.
When flag.equals("B"), it will only run test cases in test groups ={"B"},
When flag.equals("A,B"), it will only run test cases in test groups ={"A","B"}
Is there any way I can do that?
Thank you!
TestNG groups provides "flexibility in how you partition your tests" but it isn't for conditional test sets. For that you simply use plain old Java.
You can use inheritance or composition (I recommend the latter, see Item 16: Favor composition over inheritance from Effective Java).
Either way the general idea is the same: use a Factory to create your test class instances dynamically creating the appropriate class type with the appropriate test annotations and/or methods that you want to run.
Examples:
Inheritance
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
/**
* Base test class with code for both A-tests and B-tests.
*
* Note that none of these test methods are annotated as tests so that
* subclasses may pick which ones to annotate.
*/
public static abstract class BaseTest {
protected void testA() {
// test something specific to flavor A
}
protected void testB() {
// test something specific to flavor B
}
}
// extend base but only annotate A-tests
public static class FlavorATest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
}
// extend base but only annotate B-tests
public static class FlavorBTest extends BaseTest {
#Test
#Override
public void testB() {
super.testB();
}
}
// extend base and annotate both A-tests and B-tests
public static class FlavorABTest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
#Test
#Override
public void testB() {
super.testB();
}
}
}
Composition
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
private static void testA() {
// test something specific to flavor A
}
private static void testB() {
// test something specific to flavor B
}
// only create A-test methods and delegate to shared code above
public static class FlavorATest {
#Test
public void testA() {
DemoTest.testA();
}
}
// only create B-test methods and delegate to shared code above
public static class FlavorBTest {
#Test
public void testB() {
DemoTest.testB();
}
}
// create A-test and B-test methods and delegate to shared code above
public static class FlavorABTest {
#Test
public void testA() {
DemoTest.testA();
}
#Test
public void testB() {
DemoTest.testB();
}
}
}
Your factory methods won't be as simple as you'll need to use your "flag" from your test data to switch off of and create instances of the appropriate test classes.
I am trying to use Camel NettyComponent to communicate with a SocketServer written in Vert.x.
This is my server code:
public class NettyExampleServer {
public final Vertx vertx;
public static final Logger logger = LoggerFactory.getLogger(NettyExampleServer.class);
public static int LISTENING_PORT = 15692;
public NettyExampleServer(Vertx vertx) {
this.vertx = vertx;
}
private NetServer netServer;
private List<String> remoteAddresses = new CopyOnWriteArrayList<String>();
private final AtomicInteger disconnections = new AtomicInteger();
public int getDisconnections(){
return disconnections.get();
}
public List<String> getRemoteAddresses(){
return Collections.unmodifiableList(remoteAddresses);
}
public void run(){
netServer = vertx.createNetServer();
netServer.connectHandler(new Handler<NetSocket>() {
#Override
public void handle(final NetSocket socket) {
remoteAddresses.add(socket.remoteAddress().toString());
socket.closeHandler(new Handler<Void>() {
#Override
public void handle(Void event) {
disconnections.incrementAndGet();
}
});
socket.dataHandler(new Handler<Buffer>() {
#Override
public void handle(Buffer event) {
logger.info("I received {}",event);
socket.write("I am answering");
}
});
}
});
netServer.listen(LISTENING_PORT);
}
public void stop(){
netServer.close();
}
}
I tried to build a Route like the following:
public class NettyRouteBuilder extends RouteBuilder {
public static final String PRODUCER_BUS_NAME = "producerBus";
public static final String CONSUMER_BUS_NAME = "receiverBus";
private Processor processor = new Processor(){
#Override
public void process(Exchange exchange) throws Exception {
exchange.setPattern(ExchangePattern.InOut);
}
};
#Override
public void configure() throws Exception {
from("vertx:" + PRODUCER_BUS_NAME).process(processor).to("netty:tcp://localhost:"+ NettyExampleServer.LISTENING_PORT + "?textline=true&lazyChannelCreation=true&option.child.keepAlive=true").to("vertx:"+CONSUMER_BUS_NAME);
}
}
My tests shows that:
If I eliminate the processor on the route, the delivery succeed but there is no answer by the server
If I keep the processor, the data is delivered to the server but an exception raise because no data is received.
I have created a small project here: https://github.com/edmondo1984/netty-camel-vertx . How do I use Camel Netty Component to create a bidirectional route ?
To communicate Vertx and Camel the best tool is to use one of this:
Camel Vertex endpoint
Vertex Camel connector
You can find an example here
If you could or have another requeriments it is possible also to use a common connector like Netty on the both sides.
I am developing an application which uses WindowsFormsApplicationBase to enforce Single Instance. I get the following error when calling a method on a Remote object. It works fine if I don't use Single Instance approach.
System.Runtime.Remoting.RemotingException: Authentication failure ---> System.IO.IOException: Unable to read data from the transport connection: The connection was closed.
at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)
at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateAuthenticatedStream(Stream netStream, String machinePortAndSid)
Here is my Code:
public class EntryPoint
{
[STAThread]
public static void Main(string[] args)
{
SingleInstanceManager sim = new SingleInstanceManager();
sim.Run(args);
}
}
public class SingleInstanceManager : WindowsFormsApplicationBase
{
private App app;
public SingleInstanceManager()
{
IsSingleInstance = true;
}
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs eventArgs)
{
app = new App();
app.InitializeComponent();
app.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
base.OnStartupNextInstance(eventArgs);
app.Activate();
}
}
This is how I am invoking the Remoting object:
public Hashtable GetData(string[] arg1, string[] arg2)
{
IDataProvider dataProvider = (IDataProvider )Activator.GetObject(typeof(IDataProvider ), "tcp://.....");
Hashtable data = dataProvider.GetData(arg1, arg2);
return data;
}
Thanks in advance.
I found the solution myself.
I used the following to implement single instance(http://www.ai.uga.edu/mc/SingleInstance.html).
[STAThread]
static void Main() // args are OK here, of course
{
bool ok;
m = new System.Threading.Mutex(true, "YourNameHere", out ok);
if (! ok)
{
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1()); // or whatever was there
GC.KeepAlive(m); // important!
}