Kettle (Pentaho PDI): Couldn't find starting point in this job - pentaho

I'm manually creating a Job using Kettle from Java, but I get the error message Couldn't find starting point in this job.
KettleEnvironment.init();
JobMeta jobMeta = new JobMeta();
JobEntrySpecial start = new JobEntrySpecial("START", true, false);
start.setStart(true);
JobEntryCopy startEntry = new JobEntryCopy(start);
jobMeta.addJobEntry(startEntry);
JobEntryTrans jet1 = new JobEntryTrans("first");
Trans trans1 = jet1.getTrans();
jet1.setFileName("file.ktr");
JobEntryCopy jc1 = new JobEntryCopy(jet1);
jobMeta.addJobEntry(jc1);
jobMeta.addJobHop(new JobHopMeta(startEntry, jc1));
Job job = new Job(null, jobMeta);
job.setInteractive(true);
job.start();

I've discovered that I was missing
job.setStartJobEntryCopy(startEntry);

Class org.pentaho.di.job.JobMeta class has method findJobEntry
U can use it to look for entry point called "START
This is how it is original source of kettle-pdi
private JobMeta jobMeta;
....
// Where do we start?
jobEntryCopy startpoint;
....
if ( startJobEntryCopy == null ) {
startpoint = jobMeta.findJobEntry( JobMeta.STRING_SPECIAL_START, 0, false );
// and then
JobEntrySpecial jes = (JobEntrySpecial) startpoint.getEntry();

Related

How to add test case in existing test run through automation

I have created on test set and i want to add test case in existing test run . I used update request to add the test case, but its deleting existing test case in test run and adding it.
if(!testCaseList.isJsonNull()&&!update){
restApi.setApplicationName("PSN")
JsonObject newTS = new JsonObject()
newTS.addProperty("Name", TSName)
newTS.addProperty("PlanEstimate", points)
newTS.addProperty("Project", projectRef)
newTS.addProperty("Owner", userRef)
if (releaseRef!="") newTS.addProperty("Release", releaseRef)
if (iterationRef!="") newTS.addProperty("Iteration", iterationRef)
newTS.add("TestCases", testCaseList)
CreateRequest createRequest = new CreateRequest("testset",newTS)
CreateResponse createResponse = restApi.create(createRequest)
ref = createResponse.getObject().get("_ref").getAsString()
}
else if(!testCaseList.isJsonNull()&&update){
restApi.setApplicationName("PSN")
newTS.addProperty("Name", TSName)
newTS.addProperty("PlanEstimate", points)
newTS.addProperty("Project", projectRef)
newTS.addProperty("Owner", userRef)
if (releaseRef!="") newTS.addProperty("Release", releaseRef)
if (iterationRef!="") newTS.addProperty("Iteration", iterationRef)
newTS.add("TestCases", testCaseList)
UpdateRequest updateRequest = new UpdateRequest(ref,newTS)
UpdateResponse updateResponse = restApi.update(updateRequest)
ref = updateResponse.getObject().get("_ref").getAsString()
}
Rather than setting the TestCases collection directly you want to use the CollectionUpdateRequest and the updateCollection method.
https://github.com/RallyTools/RallyRestToolkitForJava/wiki/User-Guide#update-collection
CollectionUpdateRequest testsetTestCasesAddRequest = new CollectionUpdateRequest(ref + "/testcases", testCaseList, true);
CollectionUpdateResponse testsetTestCasesAddResponse = restApi.updateCollection(testsetTestCasesAddRequest);

EPiServer 9 - Add block to new page programmatically

I have found some suggestions on how to add a block to a page, but can't get it to work the way I want, so perhaps someone can help out.
What I want to do is to have a scheduled job that reads through a file, creating new pages with a certain pagetype and in the new page adding some blocks to a content property. The blocks fields will be updated with data from the file that is read.
I have the following code in the scheduled job, but it fails at
repo.Save((IContent) newBlock, SaveAction.Publish);
giving the error
The page name must contain at least one visible character.
This is my code:
public override string Execute()
{
//Call OnStatusChanged to periodically notify progress of job for manually started jobs
OnStatusChanged(String.Format("Starting execution of {0}", this.GetType()));
//Create Person page
PageReference parent = PageReference.StartPage;
//IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
//var repository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//var slaegtPage = repository.GetDefault<SlaegtPage>(ContentReference.StartPage);
IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
SlaegtPage slaegtPage = contentRepository.GetDefault<SlaegtPage>(parent, contentTypeRepository.Load("SlaegtPage").ID);
if (slaegtPage.MainContentArea == null) {
slaegtPage.MainContentArea = new ContentArea();
}
slaegtPage.PageName = "001 Kim";
//Create block
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
var newBlock = repo.GetDefault<SlaegtPersonBlock1>(ContentReference.GlobalBlockFolder);
newBlock.PersonId = "001";
newBlock.PersonName = "Kim";
newBlock.PersonBirthdate = "01 jan 1901";
repo.Save((IContent) newBlock, SaveAction.Publish);
//Add block
slaegtPage.MainContentArea.Items.Add(new ContentAreaItem
{
ContentLink = ((IContent) newBlock).ContentLink
});
slaegtPage.URLSegment = UrlSegment.CreateUrlSegment(slaegtPage);
contentRepository.Save(slaegtPage, EPiServer.DataAccess.SaveAction.Publish);
_stopSignaled = true;
//For long running jobs periodically check if stop is signaled and if so stop execution
if (_stopSignaled) {
return "Stop of job was called";
}
return "Change to message that describes outcome of execution";
}
You can set the Name by
((IContent) newBlock).Name = "MyName";

InsertAll using C# not working

I´d like to know why this code is not working. It runs without errors but rows are not inserted. I´m using C# client library.
Any ideas? Thanks!!
string SERVICE_ACCOUNT_EMAIL = "(myserviceaccountemail)";
string SERVICE_ACCOUNT_PKCS12_FILE_PATH = #"C:\(myprivatekeyfile)";
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate =
new System.Security.Cryptography.X509Certificates.X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret",
System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL)
{
Scopes = new[] { BigqueryService.Scope.BigqueryInsertdata, BigqueryService.Scope.Bigquery }
}.FromCertificate(certificate));
// Create the service.
var service = new BigqueryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "test"
});
Google.Apis.Bigquery.v2.Data.TableDataInsertAllRequest tabreq = new Google.Apis.Bigquery.v2.Data.TableDataInsertAllRequest();
List<Google.Apis.Bigquery.v2.Data.TableDataInsertAllRequest.RowsData> tabrows = new List<Google.Apis.Bigquery.v2.Data.TableDataInsertAllRequest.RowsData>();
Google.Apis.Bigquery.v2.Data.TableDataInsertAllRequest.RowsData rd = new Google.Apis.Bigquery.v2.Data.TableDataInsertAllRequest.RowsData();
IDictionary<string,object> r = new Dictionary<string,object>();
r.Add("campo1", "test4");
r.Add("campo2", "test5");
rd.Json = r;
tabrows.Add(rd);
tabreq.Rows = tabrows;
service.Tabledata.InsertAll(tabreq, "(myprojectid)", "spots", "spots");
I think you should add the Kind field [1]. It should be something like this:
tabreq.Kind = "bigquery#tableDataInsertAllRequest";
Also remeber that every request of the API has a response [2] with additional info to help you find the issue's root cause.
var requestResponse = service.Tabledata.InsertAll(tabreq, "(myprojectid)", "spots", "spots");
[1] https://developers.google.com/resources/api-libraries/documentation/bigquery/v2/csharp/latest/classGoogle_1_1Apis_1_1Bigquery_1_1v2_1_1Data_1_1TableDataInsertAllRequest.html#aa2e9b0da5e15b158ae0d107378376b26
[2] https://cloud.google.com/bigquery/docs/reference/v2/tabledata/insertAll

fetch gmail calendar events in mvc 4 application

I am working on mvc 4 web application. I want to implement a functionality wherein the scenario is as follows-
There will be gmail id as input for ex: abc#gmail.com. When user will enter this, application should fetch all the calendar events of that respective email id and display them.
I have gone through this-
http://msdn.microsoft.com/en-us/library/live/hh826523.aspx#cal_rest
https://developers.google.com/google-apps/calendar/v2/developers_guide_protocol
I am new to this and i have searched a lot but not got any solution. Please help! Thanks in advance!
Got the solution . Just refer this.
https://github.com/nanovazquez/google-calendar-sample
Please check the steps below.
Add Google Data API SDK.
Try this code.. I wrote this code for one project but I removed some codes that are not related to Google Calender. If you don't want to use SDK, you can simply do http-get or http-post to your calender link based on spec.
CalendarService service = new CalendarService("A.Name");
const string GOOGLE_CALENDAR_FEED = "https://www.google.com/calendar/feeds/";
const string GOOGLE_CALENDAR_DEFAULT_ALL_CALENDAR_FULL = "default/allcalendars/full";
const string GOOGLE_CALENDAR_ALL_PRIVATE_FULL = "private/full";
private void SetUserCredentials() {
var userName = ConfigurationManager.AppSettings["GoogleUserName"];
var passWord = Security.DecryptString(ConfigurationManager.AppSettings["GooglePasswrod"]).ToInsecureString();
if (userName != null && userName.Length > 0) {
service.setUserCredentials(userName, passWord);
}
}
private CalendarFeed GetCalendarsFeed() {
CalendarQuery calendarQuery = new CalendarQuery();
calendarQuery.Uri = new Uri(GOOGLE_CALENDAR_FEED + GOOGLE_CALENDAR_DEFAULT_ALL_CALENDAR_FULL);
CalendarFeed resultFeed = (CalendarFeed)service.Query(calendarQuery);
return resultFeed;
}
private TherapistTimeSlots GetTimeSlots(CalendarEntry entry2) {
string feedstring = entry2.Id.AbsoluteUri.Substring(63);
var postUristring = string.Format("{0}{1}/{2}", GOOGLE_CALENDAR_FEED, feedstring, GOOGLE_CALENDAR_ALL_PRIVATE_FULL);
EventFeed eventFeed = GetEventFeed(postUristring);
slot.Events = new List<Event>();
if (eventFeed != null) {
var orderEventList = (from entity in eventFeed.Entries
from timeslot in ((EventEntry)entity).Times
orderby timeslot.StartTime
select entity).ToList();
}
return slot;
}
private EventFeed GetEventFeed(string postUristring) {
var eventQuery = new EventQuery();
eventQuery.Uri = new Uri(postUristring);
var h = Convert.ToInt32(DateTime.Now.ToString("HH", System.Globalization.DateTimeFormatInfo.InvariantInfo));
eventQuery.StartTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, h, 0, 0);
eventQuery.EndTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, h + 2, 0, 0);
try {
EventFeed eventFeed = service.Query(eventQuery) as EventFeed;
return eventFeed;
}
catch (Exception ex) {
/*
* http://groups.google.com/group/google-calendar-help-dataapi/browse_thread/thread/1c1309d9e6bd9be7
*
* Unfortunately, the calendar API will always issue a redirect to give you a
gsessionid that will optimize your subsequent requests on our servers.
Using the GData client library should be transparent for you as it is taking
care of handling those redirect; but there might some times where this error
occurs as you may have noticed.
The best way to work around this is to catche the Exception and re-send the
request as there is nothing else you can do on your part.
*/
return null;
}
}

Using Rx to Geocode an address in Bing Maps

I am learning to use the Rx extensions for a Silverlight 4 app I am working on. I created a sample app to nail down the process and I cannot get it to return anything.
Here is the main code:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
var gsc = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService") as IGeocodeService;
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var myFunc = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(gsc.BeginGeocode, gsc.EndGeocode);
gcResp = myFunc(gcr) as GeocodeResponse;
if (gcResp.Results.Count > 0 && gcResp.Results[0].Locations.Count > 0)
{
returnLocation = gcResp.Results[0].Locations[0];
}
return returnLocation as IObservable<Location>;
}
gcResp comes back as null. Any thoughts or suggestions would be greatly appreciated.
The observable source you are subscribing to is asynchronous, so you can't access the result immediately after subscribing. You need to access the result in the subscription.
Better yet, don't subscribe at all and simply compose the response:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
IGeocodeService gsc =
new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var factory = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(
gsc.BeginGeocode, gsc.EndGeocode);
return factory(gcr)
.Where(response => response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
.Select(response => response.Results[0].Locations[0]);
}
If you only need the first valid value (the location of the address is unlikely to change), then add a .Take(1) between the Where and Select.
Edit: If you want to specifically handle the address not being found, you can either return results and have the consumer deal with it or you can return an Exception and provide an OnError handler when subscribing. If you're thinking of doing the latter, you would use SelectMany:
return factory(gcr)
.SelectMany(response => (response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
? Observable.Return(response.Results[0].Locations[0])
: Observable.Throw<Location>(new AddressNotFoundException())
);
If you expand out the type of myFunc you'll see that it is Func<GeocodeRequest, IObservable<GeocodeResponse>>.
Func<GeocodeRequest, IObservable<GeocodeResponse>> myFunc =
Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>
(gsc.BeginGeocode, gsc.EndGeocode);
So when you call myFunc(gcr) you have an IObservable<GeocodeResponse> and not a GeocodeResponse. Your code myFunc(gcr) as GeocodeResponse returns null because the cast is invalid.
What you need to do is either get the last value of the observable or just do a subscribe. Calling .Last() will block. If you call .Subscribe(...) your response will come thru on the call back thread.
Try this:
gcResp = myFunc(gcr).Last();
Let me know how you go.
Richard (and others),
So I have the code returning the location and I have the calling code subscribing. Here is (hopefully) the final issue. When I call GetGPSCoordinates, the next statement gets executed immediately without waiting for the subscribe to finish. Here's an example in a button OnClick event handler.
Location newLoc = new Location();
GetGPSCoordinates(this.Input.Text).ObserveOnDispatcher().Subscribe(x =>
{
if (x.Results.Count > 0 && x.Results[0].Locations.Count > 0)
{
newLoc = x.Results[0].Locations[0];
Output.Text = "Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
}
else
{
Output.Text = "Invalid address";
}
});
Output.Text = " Outside of subscribe --- Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
The Output.Text assignment that takes place outside of Subscribe executes before the Subscribe has finished and displays zeros and then the one inside the subscribe displays the new location info.
The purpose of this process is to get location info that will then be saved in a database record and I am processing multiple addresses sequentially in a Foreach loop. I chose Rx Extensions as a solution to avoid the problem of the async callback as a coding trap. But it seems I have exchanged one trap for another.
Thoughts, comments, suggestions?