How to write tests that use Azure SDK? - java

I'm wondering how I can write test, that will run in sonar, that will test the following method?
It seems almost impossible as sonar won't be able to actually get an azure subscription, so that will all have to be mocked.
Any help or pointers would be appreciated.
public AzureMetricRecords getVmMetrics(String azureSubscriptionId, String workspace, String vm, String metric, AggregationType aggregationType) {
Azure azure = getAzure(azureSubscriptionId);
String vmId = "/subscriptions/" + azureSubscriptionId + "/resourceGroups/" + workspace + "-" + vm +
"/providers/Microsoft.Compute/virtualMachines/" + vm;
VirtualMachine azureVm = azure.virtualMachines().getByResourceGroup(workspace + "-" + vm, vm);
if (azureVm != null) {
Map<String,MetricDefinition> metricsIndex = new HashMap<>();
List<MetricDefinition> definitions = azure.metricDefinitions().listByResource(vmId);
for (MetricDefinition d : definitions) {
metricsIndex.put(d.name().value(), d);
}
if (!metricsIndex.containsKey(metric)) {
throw new ValidationException("metric not found");
}
return getMetrics(DateTime.now(), metricsIndex.get(metric), aggregationType);
} else {
LOGGER.warn("getVmMetrics: Vm NOT found");
AzureMetricRecords metricRecords = new AzureMetricRecords();
metricRecords.setMetric(metric);
metricRecords.setAggregation(aggregationType.name());
return metricRecords;
}
}

When you can not get a real object for your test, you use mocks (or stubs).
In your example, as I can see, you have to mock getAzure() method, so it returns a mock of Azure type. This mock, in order, has to provide proper implementations for this
azure.virtualMachines().getByResourceGroup(workspace + "-" + vm, vm);
and this
azure.metricDefinitions().listByResource(vmId);
methods.
For mocking you can use Mockito framework, which provides a usefull API for creating and mocking objects and methods (using code or annotations).

Related

camel pollEnrich is not working for the second time

I am reading and processing 2 files from 2 different file locations and comparing the content.
If 2nd file is not available , the rest of the process execute with 1st file. If 2nd file is available, comparison process should happen. For this I am using camel pollEnrich, but here the problem is that, camel is picking the 2nd file at first time only. Without restarting the camel route 2nd file is not getting picked up even if it is present there.
After restarting the camel route it is working fine, but after that its not picking the 2nd file.
I am moving the files to different locations after processing it.
Below is my piece of code,
from("sftp:" + firstFileLocation + "?privateKeyFile=" + ppkFileLocation + "&username=" + sftpUsername
+ "&readLock=changed&idempotent=true&move=" + firstFileArchiveLocation)
.pollEnrich("sftp:" + secondFileLocation + "?privateKeyFile=" + ppkFileLocation + "&username=" + sftpUsername
+ "&readLock=changed&idempotent=true&fileExist=Ignore&move="+ secondFileLocationArchive ,10000,new FileAggregationStrategy())
.routeId("READ_INPUT_FILE_ROUTE")
Need help.
You're setting idempotent=true in the sftp consumer, which means camel will not process the same file name twice. Since you're moving the files, it would make sense to set idempotent=false.
Quoted from camel documentation
Option to use the Idempotent Consumer EIP pattern to let Camel skip
already processed files. Will by default use a memory based LRUCache
that holds 1000 entries. If noop=true then idempotent will be enabled
as well to avoid consuming the same files over and over again.
I'm adding an alternative solution based on comments for the answer posted by Jeremy Ross. My answer is based on the following code example. I've only added the configure() method in the test route for brevity.
#Override
public void configure() throws Exception {
String firstFileLocation = "//127.0.0.1/Folder1";
String secondFileLocation = "//127.0.0.1/Folder2";
String ppkFileLocation = "./key.pem";
String sftpUsername = "user";
String sftpPassword = "xxxxxx";
String firstFileArchiveLocation = "./Archive1";
String secondFileLocationArchive = "./Archive2";
IdempotentRepository repository1 = MemoryIdempotentRepository.memoryIdempotentRepository(1000);
IdempotentRepository repository2 = MemoryIdempotentRepository.memoryIdempotentRepository(1000);
getCamelContext().getRegistry().bind("REPO1", repository1);
getCamelContext().getRegistry().bind("REPO2", repository2);
from("sftp:" + firstFileLocation
+ "?password=" + sftpPassword + "&username=" + sftpUsername
+ "&readLock=idempotent&idempotent=true&idempotentKey=\\${file:name}-\\${file:size}-\\${file:modified}" +
"&idempotentRepository=#REPO1&stepwise=true&download=true&delay=10&move=" + firstFileArchiveLocation)
.to("direct:combined");
from("sftp:" + secondFileLocation
+ "?password=" + sftpPassword + "&username=" + sftpUsername
+ "&readLock=idempotent&idempotent=true&idempotentKey=\\${file:name}-\\${file:size}-\\${file:modified}" +
"&idempotentRepository=#REPO2" +
"&stepwise=true&delay=10&move=" + secondFileLocationArchive)
.to("direct:combined");
from("direct:combined")
.aggregate(constant(true), (oldExchange, newExchange) -> {
if (oldExchange == null) {
oldExchange = newExchange;
}
String fileName = (String) newExchange.getIn().getHeaders().get("CamelFileName");
String filePath = (String) newExchange.getIn().getHeaders().get("CamelFileAbsolutePath");
if (filePath.contains("Folder1")) {
oldExchange.getIn().setHeader("File1", fileName);
} else {
oldExchange.getIn().setHeader("File2", fileName);
}
String file1Name = oldExchange.getIn().getHeader("File1", String.class);
String file2Name = oldExchange.getIn().getHeader("File2", String.class);
if (file1Name != null && file2Name != null) {
// Compare files
// Both files are available
oldExchange.getIn().setHeader("PROCEED", true);
} else if (file1Name != null) {
// No comparison, proceed with File 1
oldExchange.getIn().setHeader("PROCEED", true);
} else {
// Do not proceed, keep file 2 data and wait for File 1
oldExchange.getIn().setHeader("PROCEED", false);
}
String fileName1 = oldExchange.getIn().getHeader("File1", String.class);
String fileName2 = oldExchange.getIn().getHeader("File2", String.class);
oldExchange.getIn().setBody("File1: " + fileName1 + " File2: " + fileName2);
System.out.println(oldExchange);
return oldExchange;
}).completion(exchange -> {
if(exchange.getIn().getHeader("PROCEED", Boolean.class)) {
exchange.getIn().removeHeader("File1");
exchange.getIn().removeHeader("File2");
return true;
}
return false;
}).to("log:Test");
}
In this solution, two SFTP consumers were used, instead of pollEnrich, since we need to capture the file changes of both SFTP locations. I have used an idempotent repository and an idempotent key for ignoring duplicates. Further, I've used the same idempotent repository as the lock store assuming only camel routes are accessing the files.
After receiving the files from SFTP consumers, they are sent to the direct:combined producer, which then routes the exchange to an aggregator.
In the example aggregator strategy I have provided, you can see, that the file names are being stored in the exchange headers. According to the file information retrieved from the headers, the aggregator can decide how to process the file and whether or not to proceed with the exchange. (If only file2 is received, the exchange should not proceed to the next stages/routes)
Finally, the completion predicate expression decides whether or not to proceed with the exchange and log the exchange body, based on the headers set by the aggregator. I have added an example clean-up process in the predicate expression processor as well.
Hope you will get the basic idea of my suggestion to use an aggregator from this example.

What is configuartion required to get data from object storage by SWIFT in Spark

I go through document but still it is very much confusing how to get data from swift.
I configured swift in my one linux machine. By using below command I am able to get container list,
swift -A https://acc.objectstorage.softlayer.net/auth/v1.0/ -U
username -K passwordkey list
I seen many blog for blumix(https://console.ng.bluemix.net/docs/services/AnalyticsforApacheSpark/index-gentopic1.html#genTopProcId2) and written the below code
sc.textFile("swift://container.myacct/file.xml")
I am looking to integrate in java spark. Where need to configure object storage credential in java code. Is there any sample code or blog?
This notebook illustrates a number of ways to load data using the Scala language. Scala runs on the JVM. Java and Scala classes can be freely mixed, no matter whether they reside in different projects or in the same. Looking at the mechanics of how Scala code interacts with Openstack Swift object storage should help guide you to craft a Java equivalent.
From the above notebook, here are some steps illustrating how to configure and extract data from an Openstack Swift Object Storage instance using the Stocator library using the Scala language. The swift url decomposes into:
swift2d :// container . myacct / filename.extension
^ ^ ^ ^
stocator name of namespace object storage
protocol container filename
Imports
import org.apache.spark.SparkContext
import scala.util.control.NonFatal
import play.api.libs.json.Json
val sqlctx = new SQLContext(sc)
val scplain = sqlctx.sparkContext
Sample Creds
// #hidden_cell
var credentials = scala.collection.mutable.HashMap[String, String](
"auth_url"->"https://identity.open.softlayer.com",
"project"->"object_storage_3xxxxxx3_xxxx_xxxx_xxxx_xxxxxxxxxxxx",
"project_id"->"6xxxxxxxxxx04fxxxxxxxxxx6xxxxxx7",
"region"->"dallas",
"user_id"->"cxxxxxxxxxxaxxxxxxxxxx1xxxxxxxxx",
"domain_id"->"cxxxxxxxxxxaxxyyyyyyxx1xxxxxxxxx",
"domain_name"->"853255",
"username"->"Admin_cxxxxxxxxxxaxxxxxxxxxx1xxxxxxxxx",
"password"->"""&M7372!FAKE""",
"container"->"notebooks",
"tenantId"->"undefined",
"filename"->"file.xml"
)
Helper Method
def setRemoteObjectStorageConfig(name:String, sc: SparkContext, dsConfiguration:String) : Boolean = {
try {
val result = scala.util.parsing.json.JSON.parseFull(dsConfiguration)
result match {
case Some(e:Map[String,String]) => {
val prefix = "fs.swift2d.service." + name
val hconf = sc.hadoopConfiguration
hconf.set("fs.swift2d.impl","com.ibm.stocator.fs.ObjectStoreFileSystem")
hconf.set(prefix + ".auth.url", e("auth_url") + "/v3/auth/tokens")
hconf.set(prefix + ".tenant", e("project_id"))
hconf.set(prefix + ".username", e("user_id"))
hconf.set(prefix + ".password", e("password"))
hconf.set(prefix + "auth.method", "keystoneV3")
hconf.set(prefix + ".region", e("region"))
hconf.setBoolean(prefix + ".public", true)
println("Successfully modified sparkcontext object with remote Object Storage Credentials using datasource name " + name)
println("")
return true
}
case None => println("Failed.")
return false
}
}
catch {
case NonFatal(exc) => println(exc)
return false
}
}
Load the Data
val setObjStor = setRemoteObjectStorageConfig("sparksql", scplain, Json.toJson(credentials.toMap).toString)
val data_rdd = scplain.textFile("swift2d://notebooks.sparksql/" + credentials("filename"))
data_rdd.take(5)

How to get client list using SOAP Web Services in Netsuite ERP?

I am really new to SOAP web services and to Netsuite ERP and I am trying to generate a report in my company where I need to obtain all the Clients and their Invoices using the data available in Netsuite ERP. I followed the Java and Axis tutorial they offer with their sample app for the ERP and I successfully created a Java project in Eclipse that consumes the WSDL for netsuite 2015-2 and compiles the needed classes to run the sample app. So, I followed an example found in their CRM exapmle app to obtain a Client's information but the only problem is that their example method needs you to introduce the Client's ID. Here is the sample code:
public int getCustomerList() throws RemoteException,
ExceededUsageLimitFault, UnexpectedErrorFault, InvalidSessionFault,
ExceededRecordCountFault, UnsupportedEncodingException {
// This operation requires a valid session
this.login(true);
// Prompt for list of internalIds and put in an array
_console
.write("\ninternalIds for records to retrieved (separated by commas): ");
String reqKeys = _console.readLn();
String[] internalIds = reqKeys.split(",");
return getCustomerList(internalIds, false);
}
private int getCustomerList(String[] internalIds, boolean isExternal)
throws RemoteException, ExceededUsageLimitFault,
UnexpectedErrorFault, InvalidSessionFault, ExceededRecordCountFault {
// Build an array of RecordRef objects and invoke the getList()
// operation to retrieve these records
RecordRef[] recordRefs = new RecordRef[internalIds.length];
for (int i = 0; i < internalIds.length; i++) {
RecordRef recordRef = new RecordRef();
recordRef.setInternalId(internalIds[i]);
recordRefs[i] = recordRef;
recordRefs[i].setType(RecordType.customer);
}
// Invoke getList() operation
ReadResponseList getResponseList = _port.getList(recordRefs);
// Process response from get() operation
if (!isExternal)
_console.info("\nRecords returned from getList() operation: \n");
int numRecords = 0;
ReadResponse[] getResponses = getResponseList.getReadResponse();
for (int i = 0; i < getResponses.length; i++) {
_console.info("\n Record[" + i + "]: ");
if (!getResponses[i].getStatus().isIsSuccess()) {
_console.errorForRecord(getStatusDetails(getResponses[i]
.getStatus()));
} else {
numRecords++;
Customer customer = (Customer) getResponses[i].getRecord();
_console.info(" internalId="
+ customer.getInternalId()
+ "\n entityId="
+ customer.getEntityId()
+ (customer.getCompanyName() == null ? ""
: ("\n companyName=" + customer
.getCompanyName()))
+ (customer.getEntityStatus() == null ? ""
: ("\n status=" + customer.getEntityStatus().getName()))
+ (customer.getEmail() == null ? ""
: ("\n email=" + customer.getEmail()))
+ (customer.getPhone() == null ? ""
: ("\n phone=" + customer.getPhone()))
+ "\n isInactive="
+ customer.getIsInactive()
+ (customer.getDateCreated() != null ? ""
: ("\n dateCreated=" + customer
.getDateCreated().toString())));
}
}
return numRecords;
}
So as you can see, this method needs the internal ID of each Customer which I find not useful as I have a many Customers and I don't want to pass each Customer's ID. I read their API docs (which I find hard to navigate and kind of useless) and I found a web service called getAll() that gives all the records given a getAllRecord object which requires a getAllRecordType object. However, the getAllRecordType object does not support Customer entities, so I can't obtain all the customers on the ERP this way.
Is there an easy way to obtain all the Customers in my Netsuite ERP (maybe using other thing rather than the SOAP Web Services they offer? I am desperate about this situation as understanding how Netsuite's Web Services API has been really troublesome.
Thanks!
You would normally use a search to select a list of customers. On a large account you would not normally get all customers on any regular basis. If you are trying to get the invoices you might just find it more practical to get those with a search.
You wrote "in your company". Are you trying to write an application of some sort? If this is an internal project (and even if it's not) you'll probably find using SuiteScripts much more efficient in terms of your time and frustration level.
I made it using the following code on my getCustomerList method:
CustomerSearch customerSrch = new CustomerSearch();
SearchResult searchResult = _port.search(customerSrch);
System.out.println(searchResult.getTotalRecords());
RecordList rl = searchResult.getRecordList();
for (int i = 0; i <searchResult.getTotalRecords()-1; i++) {
Record r = rl.getRecord(i);
System.out.println("Customer # " + i);
Customer testcust = (Customer)r;
System.out.println("First Name: " + testcust.getFirstName());
}

How can I get spock to execute a different method at runtime using an Annotation Extension?

First, in case there is a simpler way to solve this problem, here is an outline of what I am trying to accomplish. I want to Annotate my test methods with a KnownIssue annotation (extending AbstractAnnotationDrivenExtension) that takes a defect ID as a parameter and checks the status of the defect before executing the tests. If the defect is fixed, it will continue execution, if it is not fixed I want it to ignore the test, but if it is closed or deleted, I want to induce a test failure with logging stating that the test should be removed or updated and the annotation removed since the defect is now closed or deleted.
I have everything working up until inducing a test failure. What I have tried that doesn't work:
Throwing an exception in the visitFeatureAnnotation method, which causes a failure which causes all tests thereafter not to execute.
Creating a class that extends Spec and including a test method that logs a message and fails, then tried to use feature.featureMethod.setReflection() to set the method to execute to the other method. In this case, I get a java.lang.IllegalArgumentException : object is not an instance of declaring class
I then tried using ExpandoMetaClass to add a method directly to the declaringClass, and point feature.featureMethod.setReflection to point to it, but I still get the same IllegalArgumentException.
Here is what I have inside of my visitFeatureAnnotation method for my latest attempt:
def myMetaClass = feature.getFeatureMethod().getReflection().declaringClass.metaClass
myMetaClass.KnownIssueMethod = { -> return false }
feature.featureMethod.setReflection(myMetaClass.methods[0].getDoCall().getCachedMethod());
Any other ideas on how I could accomplish this, and either induce a test failure, or replace the method with another that will fail?
Ok... I finally came up with a solution. Here is what I got working. Within the visitFeatureAnnotation method I add a CauseFailureInterceptor that I created.
Here is the full source in case anyone is interested, just requires you to extend the KnownIssueExtension and implement the abstract method getDefectStatus:
public abstract class KnownIssueExtension extends AbstractAnnotationDrivenExtension<KnownIssue> {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(KnownIssueExtension.class)
public void visitFeatureAnnotation(KnownIssue knownIssue, FeatureInfo feature) {
DefectStatus status = null
try{
status = getDefectStatus(knownIssue.value())
} catch(Exception ex){
LOGGER.warn("Unable to determine defect status for defect ID '{}', test case {}", knownIssue.value(), feature.getName())
// If we can't get info from Defect repository, just skip it, it should not cause failures or cause us not to execute tests.
}
if (status != null){
if(!status.open && !status.fixed){
LOGGER.error("Defect with ID '{}' and title '{}' is no longer in an open status and is not fixed, for test case '{}'. Update or remove test case.", knownIssue.value(), status.defectTitle, feature.getName())
feature.addInterceptor(new CauseFailureInterceptor("Defect with ID '" + knownIssue.value() + "' and title '" + status.defectTitle + "' is no longer in an open status and is not fixed, for test case '" + feature.getName() + "'. Update or remove test case."))
}else if (status.open && !status.fixed){
LOGGER.warn("Defect with ID '{}' and title '{}' is still open and has not been fixed. Not executing test '{}'", knownIssue.value(), status.defectTitle, feature.getName())
feature.setSkipped(true)
}else if (!status.open && status.fixed){
LOGGER.error("Defect with ID '{}' and title '{}' has been fixed and closed. Remove KnownIssue annotation from test '{}'.", knownIssue.value(), status.defectTitle, feature.getName())
feature.addInterceptor(new CauseFailureInterceptor("Defect with ID '" + knownIssue.value() + "' and title '" + status.defectTitle + "' has been fixed and closed. Remove KnownIssue annotation from test '" + feature.getName() + "'."))
}else { // status.open && status.fixed
LOGGER.warn("Defect with ID '{}' and title '{}' has recently been fixed. Remove KnownIssue annotation from test '{}'", knownIssue.value(), status.defectTitle, feature.getName())
}
}
}
public abstract DefectStatus getDefectStatus(String defectId)
}
public class CauseFailureInterceptor extends AbstractMethodInterceptor{
public String failureReason
public CauseFailureInterceptor(String failureReason = ""){
this.failureReason = failureReason
}
#Override
public void interceptFeatureExecution(IMethodInvocation invocation) throws Throwable {
throw new Exception(failureReason)
}
}
class DefectStatus{
boolean open
boolean fixed
String defectTitle
}

Fitnesse extending TestResponder and overriding classpath location

I'm started using fitnesse recently and came across the issue of having to hard code my jar paths in the tests.
I came across a few old tutorials which explaing that extending test responder you can set the classpath for example for this version:
/** For FitNesse 20081115
protected String buildClassPath() throws Exception {
return super.buildClassPath() + PATH_SEPARATOR + getInheritedClassPath();
}
protected String getInheritedClassPath() {
String inheritedClasspath = "";
String parentClassPath = System.getProperty("java.class.path");
String[] classPathElements = parentClassPath.split(PATH_SEPARATOR);
for (String element : classPathElements) {
inheritedClasspath += PATH_SEPARATOR + "\"" + element + "\"";
}
return inheritedClasspath;
}
I am however using the latest version and the buildClassPath() method is not available, any ideas anyone how to go about this?

Categories