Giter VIP home page Giter VIP logo

sdk-rest's Introduction

sdk-rest

A Java client library for working with the Bullhorn REST API. Handles authentication and objectifies API operations.

Available as a Maven dependency

Add dependency to your pom file

	<dependency>
		<groupId>com.bullhorn</groupId>
		<artifactId>sdk-rest</artifactId>
		<version>1.0</version>
	</dependency>

Note, as of version 2.0.0 the SDK is built using Java 17 so the default binaries are not compatible with <17 versioned applications. If you'd like to use JRE 8 compatible binaries, add the <classifier> tag in your dependency:

	<dependency>
		<groupId>com.bullhorn</groupId>
		<artifactId>sdk-rest</artifactId>
		<version>2.0.0</version>
        <classifier>jdk8</classifier>
	</dependency>

Omission of the <classifier> tag will result in Maven downloading the JRE 17 binaries.

Basic setup:

Provide your credentials and instantiate StandardBullhornApiRest:

        BullhornRestCredentials creds = new BullhornRestCredentials();
		creds.setPassword("apipassword");
		creds.setRestAuthorizeUrl("rest.authorizeUrl");
		creds.setRestClientId("rest.clientId");
		creds.setRestClientSecret("rest.clientSecret");
		creds.setRestLoginUrl(env.getProperty("rest.loginUrl");
		creds.setRestSessionMinutesToLive("rest.sessionMinutesToLive");
		creds.setRestTokenUrl("rest.tokenUrl");
		creds.setUsername("apiusername");
		BullhornData bullhornData = new StandardBullhornData(creds);

Usage

See the unit tests for sample usage.

Use with Spring Boot

Add a configuration class:

@Configuration
@PropertySource("classpath:application-${spring.profiles.active}.properties")
public class AppConfig {

	@Autowired
	private Environment env;

	@Bean
	public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}

	/**
	 * Provide your credentials and instantiate {@link StandardBullhornData} with those.
	 * @return
	 */
	@Profile({ "staging", "production" })
	@Bean
	public BullhornData bullhornData() {

		RestCredentials creds = new BullhornRestCredentials();
        creds.setPassword("apipassword");
        creds.setRestAuthorizeUrl("rest.authorizeUrl");
        creds.setRestClientId("rest.clientId");
        creds.setRestClientSecret("rest.clientSecret");
        creds.setRestLoginUrl(env.getProperty("rest.loginUrl");
        creds.setRestSessionMinutesToLive("rest.sessionMinutesToLive");
        creds.setRestTokenUrl("rest.tokenUrl");
        creds.setUsername("apiusername");
		return new StandardBullhornData(creds);

	}

	/**
	 * Using {@link MockBullhornData} for testing purposes. This implementation of {@link BullhornData} uses test data stored in local
	 * text files.
	 * 
	 * @return
	 */
	@Profile("testing")
	@Bean
	public BullhornData mockBullhornData() {

		return new MockBullhornData();

	}
}

sdk-rest's People

Contributors

acrowe2 avatar alnaua avatar awubullhorn avatar aymansaad7777 avatar betulalenta avatar bullhorn-adye avatar bullhorn-pmckinstry avatar ccarbonellbh avatar dependabot[bot] avatar dhuberbh avatar fayranne avatar hiqbal01 avatar hkkin2 avatar jlrutledge-bh avatar johnsully83 avatar luke-grey avatar maartenoortwijn avatar mikecogle avatar mkesmetzis avatar mohamedmahmoud299 avatar monroepe avatar ndickerson avatar racine-bh avatar scriptom avatar shylendrapandravisam avatar taswartz avatar tgadre avatar thegiddylimit avatar tkennedy0617 avatar vonterio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sdk-rest's Issues

Rest login not working sporadically

Trying to login to BH by using the REST SDK fails sporadically, but we are able to retry and successfully send them over at a later time

Here are the different error messages we get :

  1. com.bullhornsdk.data.exception.RestApiException: Failed to create rest session

  2. com.bullhornsdk.data.exception.RestApiException: Failed to login and get BhRestToken: {"errorMessageKey":"errors.internalError","errorMessage":"Invalid or expired OAuth access token.","errorCode":400} 

  3. com.bullhornsdk.data.exception.RestApiException: Failed to login and get BhRestToken: null

However, when we see these deadletters we are able to successfully resend them later on. Why does this happen?

API Authentication Issue

Hi Team,

The Authentication fails with the below exception
Exception in thread "main" com.bullhornsdk.data.exception.RestApiException: Failed to create rest session
at com.bullhornsdk.data.api.helper.RestApiSession.createSession(RestApiSession.java:136)
at com.bullhornsdk.data.api.helper.RestApiSession.(RestApiSession.java:88)
at com.bullhornsdk.data.api.StandardBullhornData.(StandardBullhornData.java:165)
at com.avrio.bullhorn.BullhornPullUtil.main(BullhornPullUtil.java:101)
Caused by: com.bullhornsdk.data.exception.RestApiException: Failed to get authorization code.
at com.bullhornsdk.data.api.helper.RestApiSession.getAuthorizationCode(RestApiSession.java:165)
at com.bullhornsdk.data.api.helper.RestApiSession.createSession(RestApiSession.java:126)
... 3 more
Caused by: java.lang.NullPointerException
at com.bullhornsdk.data.api.helper.RestApiSession.getAuthCode(RestApiSession.java:191)
at com.bullhornsdk.data.api.helper.RestApiSession.getAuthorizationCode(RestApiSession.java:162)
... 4 more

Let me know if you need anything else.

DistributionList

We should add the DistributionList objet and it's members association

Call to resume/parseToCandidate returns invalid candidate object with certain resume

Hi Bullhorn Team,

I met you at the Bullhorn Engage Conference. I am one half of Matador Jobs (for WordPress) and a Marketplace Partner. I asked a question during the Developer Q&A where to submit bug reports for the API, and I was told here (even though this GH isn't for the REST API per se). So here goes.

I have a client who has received two applications this week that have caused Matador to fail. Here is what is happening (normally):

  • Matador, submits the candidates' resume file to Bullhorn via a resume/parseToCandidate call.
  • Matador manipulates the object
  • Matador, tries to create a candidate with the returned object.

For this candidate, the call fails. The error is:

stdClass Object ( [errorMessage] => error persisting an entity of type: Candidate [errorMessageKey] => errors.cannotPersistEntity [errorCode] => 500 [errors] => Array ( [0] => stdClass Object ( [propertyName] => nameSuffix [maxLength] => 5 [severity] => ERROR [type] => PROPERTY_VALUE_TOO_LONG ) ) [entityName] => Candidate )

To narrow down this bug, I turned off any manipulation of the object. So my test runs in exactly this order:

  • Submit resume to resume/parseToCandidate
  • Submit returned object to entity/Candidate

The call still failed with the same error. So I inspected the returned object from the resume/parseToCandidate call. I found this:

object(stdClass)#1158 (5) { ["confidenceScore"]=> string(5) "58.33" ["candidate"]=> object(stdClass)#1159 (10) { ["omitted_fields_for_security]=> (...), ["nameSuffix"]=> string(29) "Oracle Certified Professional" } }

Note: Because this a real candidate, I omitted sensitive data, but a firstName, lastName, and more was present, as expected.

So, I am confident I've narrowed this to resume/parseToCandidate returning an invalid candidate object. This is a pretty rough bug, and I hope you agree. I understand why namePrefix has a character limit, but I don't understand why the parser is giving me an invalid object back.

To address this issue while you work on this, Matador is seeing its error handling improved in this area, but ultimately, this is not something we can fix. We do not want to, nor do we think we should need to, write a validator for data returned to us via the API. The candidate object is massive and a validator will cost resources and processing time we don't want, and we feel strongly that what we get back from Bullhorn should be reliable.

I am 100% committed to helping the team address this issue and in fact have the resume in question (client data and all) available for you guys to use in recreating this bug. Please, email me at jeremy - at - matadorjobs - dot - com and I'll send you the candidates resume so you can recreate this error. I am not on GH every day (like I am on bitbucket) so the fastest replies for me might be via email.

Error when inserting notes

Hi,
I have started using the Bullhorn API a few days ago , and working on the integration.
I tried to add Notes to candidate in two ways (both failed)

  1. Using the candidate:
    candidate.setNotes(OneToMany notes)

I get this warning on the candidate update and the note is not added:

 UpdateResponse {
changedEntityType=Candidate, 
changedEntityId=18, 
changeType=UPDATE, 
messages=[ {
detailMessage=null, 
propertyName=notes, 
severity=WARNING, 
type=ATTEMPT_TO_SET_TO_MANY
}], 
errorCode=, 
errorMessage=
}>
  1. Using the addNoteAndAssociateWithEntity()
    I get exceptions but the note is inserted.

com.bullhornsdk.data.exception.RestApiException: {
  "errorMessage" : "error persisting an entity of type: NoteEntity",
  "errorMessageKey" : "errors.cannotPersistEntity",
  "errorCode" : 500,
  "errors" : [ {
    "propertyName" : null,
    "severity" : "ERROR",
    "type" : "DUPLICATE_VALUE"
  } ],
  "entityName" : "NoteEntity"
}
	at com.bullhornsdk.data.api.StandardBullhornData.handleHttpStatusCodeError(StandardBullhornData.java:1855)
	at com.bullhornsdk.data.api.StandardBullhornData.performCustomRequest(StandardBullhornData.java:1832)
	at com.bullhornsdk.data.api.StandardBullhornData.handleInsertEntity(StandardBullhornData.java:1036)
	at com.bullhornsdk.data.api.StandardBullhornData.insertEntity(StandardBullhornData.java:313)
	at com.bullhornsdk.data.api.StandardBullhornData.handleAddNoteAndAssociateToEntity(StandardBullhornData.java:617)
	at com.bullhornsdk.data.api.StandardBullhornData.addNoteAndAssociateWithEntity(StandardBullhornData.java:544)

This is how I create the note:

	Person commentingPerson = new Person(1);
	Person personReference = new Person(candidateId);
	Note note = new Note();
	note.setCommentingPerson(commentingPerson);
	note.setPersonReference(personReference);
	note.setComments("my comment"));

Is this a bug or am I doing something wrong?

The endpoint /entityFiles/{entityType}/{entityId} is deprecated and replaced with a new one

According to the Bullhorn API documentation here, the request “GET /entityFiles/{entityType}/{entityId}” is deprecated and replaced with the new one “GET /entity/{entityType}/{entityId}/fileAttachments”.

The method RestUrlFactory.assembleGetEntityMetaFilesUrl() (/src/main/java/com/bullhornsdk/data/api/helper/RestUrlFactory.java) is returning the deprecated endpoint url “entityFiles/{entityType}/{entityId}”, which is being used to get the File metadata for an entity record.

Does this request need to be replaced with the new one “GET /entity/{entityType}/{entityId}/fileAttachments” before the current one stops working if it hasn’t already?

MAX_TTL value?

In the RestApiSession class the value of the MAX_TTL is set to 2880 minutes. I would like to know if this is the limit value of the ttl set by the BullHorn API or was it just 'randomly' (or whatever reason was) chosen by developers of this SDK?

In Other words, if I send a request directly (from postman) with the query value ttl > 2880 what will be the ttl of the returned BhRestToken?

Placement field reportedMargin is a Double in the API, but an Integer in the SDK

As per title.

For instance, a Placement with reportedMargin of 0.625 (as visible through the API) is read as the Integer 0 if accessed via the SDK.

To reproduce:

BullhornData bullhornData = new StandardBullhornData( ...etc... );
StandardListWrapper<Placement> test = bullhornData.search(Placement.class, "id:*ID of placement with decimal reportedMargin*", Sets.newHashSet("reportedMargin"), ParamFactory.searchParams());
System.out.println(test.getData().get(0).getReportedMargin());

Allow Null Date Values

Date values start out as null (no value). Once a date value is set, it can never be unset back to null.

The current implementation of the object mapper ignores all null values, including date values, and only a null value can set the date back to it's original empty state. The proper JSON payload for setting a null date value is:

{
    "customDate1": null
}

This is not currently achievable with the global Jackson annotation:

@JsonInclude(JsonInclude.Include.NON_NULL)

Which is used in order to avoid race conditions that occur when sending all values, including null values that were not set on the entity object. In order to support the sending of null values for dates, there will have to be special logic that determines when a user has explicitly set a null value on the date, and distinguish that from the initial default state of the object.

Client has recently stopped working with "Failed to get Authorization code" (Failed to create rest session)

I am using the Bullhorn Java SDK to retrieve candidate data. Up until this morning I was able to authenticate and execute filter searches by creating a new StandardBullhornData instance.

Now the creation of the StandardBullHornData class fails with an "Unable to create rest client" exception. Looking at the stack trace I can see that the underlying cause is a null pointer exception in RestApiSession.getAuthCode() because a URI being returned from restTemplate.postForLocation() is null. It appears to me that this method (postForLocation) is always expecting a 302 response with a "Location" header, but when I examine the response for the request (the third request in the authentication sequence) the status code is 200, and there is no Location header, resulting in a null pointer exception

It is entirely possible that an infrastructure issue is causing this, but I have no way of telling what is going wrong.

I am using the following URLs:

REST token URL: https://rest-aus.bullhornstaffing.com/oauth/token
REST Authorize URL: https://rest-aus.bullhornstaffing.com/oauth/authorize
REST Login URL: https://rest-aus.bullhornstaffing.com/rest-services/login

I have tested with versions 1.5.47 and 1.4.49 of the SDK, and I have not changed the credentials, client secret or anything else.

It seems to me that at the very least that the SDK should deal with the 200 response

Implementation mistake in StandardBullhornData.java

In the handleHttpStatusCodeError method, when it throws a RestApiException there are no parentheses around the ternary conditional error == null ? "" : error.getResponseBodyAsString().

This means that the error object is concatenated onto the preceding exception message before it is compared to null. The effect of which is that the exception message will always and only contain the response body string, never the uri variables or http status code.

Source of method

Error messages from bullhorn REST SDK not helpful in debugging issues

  1. Rest API fails with generic messages leaving no way to diagnose the issue. Generic messages such as

We get the following exceptions on calls such as findEntity and insertEntity that does not explain why it fails so we are unable to deduce if this is caused by bad data on our end or something else

com.bullhornsdk.data.exception.RestApiException: { "errorMessage" : "An internal error has occurred", "errorMessageKey" : "errors.internalError" } 

  1. updateEntity fails and the response object returned has response.isError() set to true but other data to help diagnose such as response.getErrorCode() and response.getErrorMessage() are not present. Another case where it is not possible to diagnose the issue.

dateLastPublished on JobOrder isn't available through the SDK

dateLastPublished on JobOrder is available through metadata/to be searched upon, but not available on the SDK to pull.

http://bullhorn.github.io/rest-api-docs/entityref.html#joborder

This would benefit cube19 as we have a client who wants to monitor when Jobs are published and which Jobs are published. Though there is a "Publishing Status" field available so we know a Job has been published, knowing when it happens is key for the metrics the client wants to report over.

#Error while inserting CandidateCertification

Hi Team,

I was trying to persist candidateCertification entity which has fileAttachment field in it.
It is OneToMany field but I can't use 'associateWithEntity()' method as StandardFileAttachment.class is not extending BullhornEntity class. Hence, I tried as below:

CandidateCertification candidateCertification = new CandidateCertification();
Candidate cand= bullhornData.findEntity(Candidate.class, candidateId);
candidateCertification.setCandidate(cand);
Certification cert= bullhornData.findEntity(Certification.class, certId);
candidateCertification.setCertification(cert);
StandardFileAttachment standardFileAttachment = new StandardFileAttachment();
standardFileAttachment.setCandidate(cand);
standardFileAttachment.setId(fileId);
standardFileAttachment.setName(fileName);
OneToMany oneToMany = new OneToMany<>();
oneToMany.setData(Arrays.asList(standardFileAttachment));

        candidateCertification.setFileAttachments(oneToMany);
        CrudResponse crudResponse1 = bullhornData.insertEntity(candidateCertification); 

Below is the error while inserting record:
{ detailMessage=null,
propertyName=fileAttachment, severity=WARNING,
type=ATTEMPT_TO_SET_TO_MANY }

Could you please check the issue once OR suggest if we have any other way to achieve it.

Thanks!
Verinder

README.md is wrong about initial setup

Currently using v1.2.48.

We are advised to start with RestCredentials creds = new BullhornRestCredentials();, but it doesn't work.

In fact, BullhornRestCredentials does not implement RestCredentials and thus this operation is illegal in Java.

The solution for the users of this library is quite trivial: BullhornRestCredentials creds = new BullhornRestCredentials();. But that's not really idea.

This should be a fairly easy fix in the codebase which would be backward compatible with the current state of things. I just thought I'd let you know so that you can update either the README or the code.

EarnCode fields removal

Hi,

It seems that isDeleted and status were removed from EarnCode in the API. Can we please confirm it is permanent or just a bug? If it is permanent, can we have them removed from the SDK too? Thanks.

GET: /query/EarnCode?fields=id,isDeleted&where=id>0

errorMessage "Invalid field 'isDeleted' at position 4."
errorMessageKey "errors.invalidField"
errorCode 400

GET: /query/EarnCode?fields=id,status&where=id>0

errorMessage "Invalid field 'status' at position 4."
errorMessageKey "errors.invalidField"
errorCode 400

Not able to set value of field workersCompRateID in placement

I am using SDK Rest Api for update

Placement entity workersCompRateID not able to update

Step 1
i am using sdk-rest version is 1.2.48

com.bullhorn
sdk-rest
1.2.48

Step 2

Placement placementRecord = bullhornData.findEntity(Placement.class, rateCalculatorVO.getBhPlacementId().intValue());
try

	{
		
	WorkersCompensationRate workersCompensationRate= new WorkersCompensationRate();
	workersCompensationRate.setId(10);
	BigDecimal ratevar = BigDecimal.valueOf(1.00);
	workersCompensationRate.setRate(ratevar);
	
	logger.warn(System.getProperty("user.timezone"));
	SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
	String dateInString = rateCalculatorVO.getStartDate();
	Date startDate = sdf.parse(dateInString);
	logger.warn("startDate = " + startDate);
	Calendar calNewYork = Calendar.getInstance();
	calNewYork.setTimeZone(TimeZone.getTimeZone("America/New_York"));
	logger.warn("StartDate TimeInMillis = " + calNewYork.getTimeInMillis());
	startDate.setHours(calNewYork.getInstance().getTime().getHours());
	startDate.setMinutes(calNewYork.getInstance().getTime().getMinutes());
	startDate.setSeconds(calNewYork.getInstance().getTime().getSeconds());
	logger.warn("StartDate and Time = " + startDate);
	DateTime dateBegin = new DateTime(startDate);
	logger.warn("dateBegin  = " + dateBegin);
	workersCompensationRate.setStartDate(dateBegin);
	workersCompensationRate.setEndDate(dateBegin);
	
	PrivateLabel privateLabel = new PrivateLabel();
	 privateLabel.setId(18537);
	 privateLabel.setName("American Cybersystems (Dev)");
	 privateLabel.setTitle("American Cybersystems (Dev)");
	
	 privateLabel.setType("Base");
	
	 privateLabel.setNoLookAndFeel(0);
	 
	workersCompensationRate.setPrivateLabel(privateLabel);
	
	
	WorkersCompensation  workersCompensation= new WorkersCompensation();
	workersCompensation.setId(10);
	workersCompensation.setCode("dummy");
	workersCompensation.setDescription("dummy");
	workersCompensation.setName("dummy");
	workersCompensation.setState("dummy");
	
	
	workersCompensationRate.setCompensation(workersCompensation);
	
	//Not able to set value of field workersCompRateID in placement
	placementRecord.setWorkersCompensationRate(workersCompensationRate);
	placementRecord.setComments("dummy1111");
	}
	catch(Exception e)
	{
		e.getMessage();
	}
	finally
	{
		
	}

Step3

image

"I got Response message like this "
detailMessage=associated entity workersCompensationRate with ID 10 not found,
propertyName=workersCompensationRate,
severity=WARNING,
type=ASSOCIATED_ENTITY_NOT_FOUND

UpdateResponse {
changedEntityType=Placement,
changedEntityId=51852,
changeType=UPDATE,
messages=[ {
detailMessage=read only property: dateLastModified,
propertyName=dateLastModified,
severity=WARNING,
type=READ_ONLY_FIELD
}, {
detailMessage=associated entity workersCompensationRate with ID 10 not found,
propertyName=workersCompensationRate,
severity=WARNING,
type=ASSOCIATED_ENTITY_NOT_FOUND
}, {
detailMessage=null,
propertyName=housingAmenities,
severity=WARNING,
type=ATTEMPT_TO_SET_TO_MANY
}, {
detailMessage=null,
propertyName=owners,
severity=WARNING,
type=ATTEMPT_TO_SET_TO_MANY
}, {
detailMessage=null,
propertyName=fileAttachments,
severity=WARNING,
type=ATTEMPT_TO_SET_TO_MANY
}, {
detailMessage=null,
propertyName=notes,
severity=WARNING,
type=ATTEMPT_TO_SET_TO_MANY
}],
errorCode=,
errorMessage=
}

I had also try second set of code

Placement placementRecord = bullhornData.findEntity(Placement.class, rateCalculatorVO.getBhPlacementId().intValue());
	try
	
	{
		
	WorkersCompensationRate workersCompensationRate= new WorkersCompensationRate();
	workersCompensationRate.setId(10);
	BigDecimal ratevar = BigDecimal.valueOf(1.00);
	workersCompensationRate.setRate(ratevar);
	
	logger.warn(System.getProperty("user.timezone"));
	SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
	String dateInString = rateCalculatorVO.getStartDate();
	Date startDate = sdf.parse(dateInString);
	logger.warn("startDate = " + startDate);
	Calendar calNewYork = Calendar.getInstance();
	calNewYork.setTimeZone(TimeZone.getTimeZone("America/New_York"));
	logger.warn("StartDate TimeInMillis = " + calNewYork.getTimeInMillis());
	startDate.setHours(calNewYork.getInstance().getTime().getHours());
	startDate.setMinutes(calNewYork.getInstance().getTime().getMinutes());
	startDate.setSeconds(calNewYork.getInstance().getTime().getSeconds());
	logger.warn("StartDate and Time = " + startDate);
	DateTime dateBegin = new DateTime(startDate);
	logger.warn("dateBegin  = " + dateBegin);
	workersCompensationRate.setStartDate(dateBegin);
	workersCompensationRate.setEndDate(dateBegin);
	
	workersCompensationRate.setPrivateLabel(privateLabel);
	
	workersCompensationRate.setCompensation(workersCompensation);
	
	//Not able to set value of field workersCompRateID in placement
	placementRecord.setWorkersCompensationRate(workersCompensationRate);
	placementRecord.setComments("dummy1111");
	}
	catch(Exception e)
	{
		e.getMessage();
	}
	finally
	{
		
	}

"I got Response message like this "
detailMessage=associated entity workersCompensationRate with ID 10 not found,
propertyName=workersCompensationRate,
severity=WARNING,
type=ASSOCIATED_ENTITY_NOT_FOUND

i had gone to bullhorn docs
image

I**t is required to set all associated object values to ? for update the workersCompRateID

//Not able to set value of field workersCompRateID in placement
placementRecord.setWorkersCompensationRate(workersCompensationRate);**

it very urgent and my production build stuck

please guild me and share me some code for update some value in workersCompRateID in placement entity with the help of sdk-rest version is 1.2.48.

sdk-rest updateEntity method for candidate returns "missing required property: userType"

To Whom It May Concern:

I am implementing a Java client of the Bullhorn Platform SDK library called sdk-rest (version 1.2.3). I am trying to update a candidate entity with the call:

UpdateResponse response = bhData.updateEntity(e);

where e is an instance of com.bullhornsdk.data.model.entity.core.standard.Candidate that I retrieved using the findEntity method.

However, I am getting the following error message:

com.bullhornsdk.data.exception.RestApiException: { "errorMessage" : "error persisting an entity of type: Candidate", "errors" : [ { "detailMessage" : "missing required property: userType", "propertyName" : "userType", "severity" : "ERROR", "type" : "MISSING_REQUIRED_PROPERTY" } ], "entityName" : "Candidate" }

Please tell me the recommended solution for this issue.

Thanks,

Steve Hiller
Senior Analyst/Programmer

Randstad USA
2050 Spectrum Blvd
Fort Lauderdale, FL 33309
954.308.8230 (o)
[email protected]......
http://www.randstad.com

StandardBullhornData Should Properly Handle Rate-Limiting

The REST API is behind a gateway that will rate-limit connections that burst too high in traffic, and the SDK does not properly handle the 429 Responses. The methods that make REST calls into our API should properly handle a 429 response.

The functions:

  • performGetRequest
  • performPostRequest
  • performCustomRequest

Approach:

  • When receiving the 429 response, the SDK should sleep for a second and then retry the request. Note that this should not be susceptible to the API_RETRY limit, so it can't simply be added to handleHttpStatusCodeError without some minor refactoring to that function.

sdk-rest addNoteAndAssociateWithEntity method returns DUPLICATE_VALUE - 02419504

To Whom It May Concern:

I am implementing a Java client of the Bullhorn Platform SDK library called sdk-rest (version 1.2.3). I am trying to insert a note with the following code:

Note note = new Note(); note.setComments(comments); note.setIsDeleted(Boolean.FALSE); note.setPersonReference(new Person(foCandidateId)); note.setJobOrder(new JobOrder(jobOrderId)); note.setDateAdded(DateTime.now()); CrudResponse response = bhData.addNoteAndAssociateWithEntity(note);

This returns the following error:

com.bullhornsdk.data.exception.RestApiException: { "errorMessage" : "error persisting an entity of type: NoteEntity", "errors" : [ { "propertyName" : null, "severity" : "ERROR", "type" : "DUPLICATE_VALUE" } ], "entityName" : "NoteEntity" }

If I dig down to the com.bullhornsdk.data.api.StandardBullhornData.performCustomRequest() method, I see that the underlying exception is:

org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error

lease tell me the recommended solution for this issue.

Thanks,

Steve Hiller
Lead Analyst/Programmer

Randstad USA
2050 Spectrum Blvd
Fort Lauderdale, FL 33309
954.308.8230 (o)
[email protected]

Is 1.2.48 an actual release?

1.2.48 has been released on Maven and the code looks to be in a release state with the dropping of SNAPSHOT on the version in the POM but this looks to have not been officially releases on the Github page.

Many thanks,

Andrew

Setting BhrestToken session time does not work

BullhornRestCredentials creds = new BullhornRestCredentials();
creds.setPassword("apipassword");
creds.setRestAuthorizeUrl("rest.authorizeUrl");
creds.setRestClientId("rest.clientId");
creds.setRestClientSecret("rest.clientSecret");
creds.setRestLoginUrl(env.getProperty("rest.loginUrl");
creds.setRestSessionMinutesToLive("rest.sessionMinutesToLive");
creds.setRestTokenUrl("rest.tokenUrl");
creds.setUsername("apiusername");
BullhornData bullhornData = new StandardBullhornData(creds);

The line of code "creds.setRestSessionMinutesToLive("rest.sessionMinutesToLive")" used for setting the session expiration time limit ,if I am not wrong.
But even i set it to around 20 days ,it keeps getting expired before 1 day.

1.I want to know that this is the only way to set the session expiration or any other way.
2. is there any max time limit for the session to live property.

Cannot able to update a candidate

[FATAL]: local_project.sdkrouting_0_1.sdkrouting - tJavaRow_1 {
"errorCode" : 500,
"errors" : [ {
"detailMessage" : "missing required property: userType",
"propertyName" : "userType",
"severity" : "ERROR",
"type" : "MISSING_REQUIRED_PROPERTY"
} ],
"entityName" : "Candidate",
"errorMessage" : "error persisting an entity of type: Candidate"
}
com.bullhornsdk.data.exception.RestApiException: {
"errorCode" : 500,
"errors" : [ {
"detailMessage" : "missing required property: userType",
"propertyName" : "userType",
"severity" : "ERROR",
"type" : "MISSING_REQUIRED_PROPERTY"
} ],
"entityName" : "Candidate",
"errorMessage" : "error persisting an entity of type: Candidate"
}

UserType class does not have the parameter based constructor.
Please help

concurrent modification exception on association list

The actual bug is in allAssociations() method:

 if (allAssociations == null) {
            allAssociations = new ArrayList<AssociationField<Candidate, ? extends BullhornEntity>>();
            allAssociations.add(businessSectors());
...

it is the same for all association entities


java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
        at java.util.ArrayList$Itr.next(ArrayList.java:851)
        at com.bullhornsdk.data.model.entity.association.standard.CandidateAssociations.getAssociation(CandidateAssociations.java:162)
        at com.bullhornsdk.data.model.entity.association.AssociationFactory.getAssociationField(AssociationFactory.java:50)

using version 1.2.10

Remove willRelocateInt field from JobOrder entity

Must have been legacy something or other, doesn't seem to be doing anything now, and if you request the field in a fields parameter, this is returned

{
"errorMessage": "Invalid field 'willRelocateInt' at position 14."
}

Comment Field

Hi,

I'm not particular familiar with APIs, but Bullhorn Support pointed me to this thread to ask my question.

Is it possible via Bullhorn's API to pull the content out of the candidate general comments field & the contact general comments field, (restructure it if necessary) and then again via API feed this content back into a dropdown or picker field in the corresponding candidate/contact records?
If it is possible, our organisation would consider hiring a developer to do implement it.

CandidateReference: customTextBlock lengths incorrect

The CandidateReference entity appears to have the wrong length (255) reported for customTextBlock1 to 3.

com.bullhornsdk.data.exception.RestApiException: {
"errorMessage" : "error persisting an entity of type: CandidateReference",
"errorMessageKey" : "errors.cannotPersistEntity",
"errorCode" : 500,
"errors" : [ {
"propertyName" : "customTextBlock1",
"maxLength" : 255,
"severity" : "ERROR",
"type" : "PROPERTY_VALUE_TOO_LONG"
} ],
"entityName" : "CandidateReference"
}

Setting dateAdded with PUT file (raw)

Currently, it's possible to set fileAttachment dateAdded by using setDateAdded(<<DateTime>>) on a FileMeta instance, and passing this to addFile e.g. <<StandardBullhornData>>.addFile(Candidate.class, 1234, fileMeta);

This will correctly set the dateAdded on the file. However, there doesn't seem to be an equivalent for the "raw" version of addFile (when sending multipart/form data). Could this be implemented?

Search for JobOrders using SDK throws error when parsing address

Hey there fellas!

I'm part of a company which uses bullhorn SDK, lately we are running into a issue when requesting the Address object from Job orders, which seems to be caused by a missing field named ‘countryCode’.

The previous version we used were 1.4.50, but it started to show issues regarding authorization and authentication through the SDK.
com.bullhornsdk.data.api.helper.RestApiSession - Failed to get access token.

It used to work before and even works fine when requesting through postman. Hence, we decided to update the SDK version

So currently we are running the SDK new version 2.2.2, in a grails environment version 3.1.16. We are using gradle as dependency management and listing the SDK dependency as such:
compile 'com.bullhorn:sdk-rest:2.2.2:jdk8', using the classifier :jdk8 as recommended in the README for java 8 compatibility.

The method we’re invoking which is ultimately causing the error is the BullhornData.searchForList(Class type, String query, Set fieldSet, SearchParams params)

When supplying the ‘address’ in the fieldSet parameter, we got the following error:


org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: org.apache.logging.log4j.Logger.debug(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V (through reference chain: com.bullhornsdk.data.model.response.list.JobOrderListWrapper["data"]->java.util.ArrayList[0]->com.bullhornsdk.data.model.entity.core.standard.JobOrder["address"]->com.bullhornsdk.data.model.entity.embedded.Address["countryCode"]);

nested exception is com.fasterxml.jackson.databind.JsonMappingException: org.apache.logging.log4j.Logger.debug(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V (through reference chain: com.bullhornsdk.data.model.response.list.JobOrderListWrapper["data"]->java.util.ArrayList[0]->com.bullhornsdk.data.model.entity.core.standard.JobOrder["address"]->com.bullhornsdk.data.model.entity.embedded.Address["countryCode"])

We tried matching the jackson library used by the SDK (seemly 2.10.0)
Setting up a custom ObjectMapper and explicitly setting DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES as FALSE did not solved the problem either.

Also some other options were given a chance, like using the searchForIdList and findMultipleEntity passing the ids returned from the first method.

In this case, no error occurred, but if ‘address’ is NOT requested, a null object returns, yet we do have a result set. If ‘address’ IS requested, though, no result set returned from findMultipleEntity method.

I believe this is all we got so far, let me know if I can provide anymore information.

Thanks in advance!

com.bullhornsdk.data.exception.RestMappingException:

Posting here per BHSupport

When using the following
findEntity(com.bullhornsdk.data.model.entity.core.standard.Candidate.class, xxxxxxx)
we get
com.bullhornsdk.data.exception.RestMappingException:
Error mapping jsonString to class com.bullhornsdk.data.model.entity.core.standard.Candidate. jsonString =

This is not on all candidates, but have not figured out what is different about the subset of candidates that cause this.

Resume parsing API failing when resume not contains email address.

Hi ,
We are using below API to parse the candidate resume.

https://rest1.bullhornstaffing.com/rest-services/3w4y1/resume/parseToCandidate?format=DOCX&populateDescription=html&BhRestToken=xxxxxxxx

The API working fine if the resume has email address , but if the resume doesn't have email address then it's giving below error.

{
"errorMessageKey": "errors.internalError",
"errorMessage": "An internal error has occurred"
}

We were told that email address is not a required field and resume parser API should work without email address , but in our case it's failing with above mentioned error.

Attached is the screenshots of two cases , where resume parsing is successful when there is email address and failure when there is no email address.

We have also attached the resume which is failing.

Could you check and let us know why it's failing when email address not there in resume.
resume_parsing_failing
resume_parsing_success
sample_resume_without_email.docx

Retrieve list of CorporateUser and update its customText fields

I am able to retrieve an individual CorporateUser using this line:

CorporateUser corporateUser = standardBullhornData.findEntity(CorporateUser.class, id);
but I need to retrieve the list of all CorporateUser and I could not find a way to do it ?

Also how to update a customText field of a CorporateUser ?
CorporateUser corporateUser = new CorporateUser(corporateUserId);
corporateUser.setCustomText1("Test");
standardBullhornData.updateEntity(corporateUser); // <== this is not allowed as CorporateUser is not an Entity

Silent failures during "findMultipleEntity" calls

RestApiExceptions thrown during "findMultipleEntity" are silently discarded and an empty list returned. This makes debugging and even detection of issues quite a bit harder.

Is this an intentional decision in the SDK design or can it be fixed? (I guess backwards compatibility would require it to be a new method instead of a change to the existing method).

My current workaround has been to reimplement the contents of the "StandardBullhornData.findMultipleEntity" method in my own code whilst removing outermost try/catch.

Note ID ordering is alphabetical

To reproduce:

BullhornData bullhornData = ... // init StandardBullhornData
Set<String> fs = new HashSet<>();
fs.add("id");
SearchParams p = ParamFactory.searchParams();
p.setSort("-noteID");
ListWrapper<Note> ns = bullhornData.search(Note.class, "*:*", fs, p);
System.out.println(ns.getData().stream().map(BullhornEntity::getId).map(Object::toString).reduce((a, b) -> a+", "+b).get());

Expected: 1868, 1867, 1866, ... (highest note ID on this instance is 1868)
Actual: 999, 998, 997, ...

It appears the results are sorted alphabetically (desc), with numbers beginning with 9 coming before larger numbers beginning with 1.

Division field on Lead

error while updating /creating the client corporation

i was getting the following error while updating a clientCorporation
"errorMessage" : "error persisting an entity of type: ClientCorporation",
"errorMessageKey" : "errors.cannotPersistEntity",
"errorCode" : 500,
"errors" : [ {
"detailMessage" : "",
"propertyName" : "",
"severity" : "ERROR",
"type" : "UNKNOWN_INTERNAL_ERROR"
} ],
"entityName" : "ClientCorporation"

I searched everywhere but of no help.
I found that this error was occurred due to maximum length of address1 field is 40 which no one can guess from the error log .
I did lots of hit and trial and found that in client corp data model its max length is 40 only .

SOLVED

"Invalid characters in file name!" "errorCode" : 400 - What are the invalid characters.

Using the SDK to upload files to Bullhorn but I was getting this error on file names that seemed to have no invalid characters in them:

"Invalid characters in file name!" "errorCode" : 400

Are you able to supply a list of characters or strings that the back end Rest function is looking for so I can make sure I am checking them on the front end also.

Many thanks,

Andrew

Cannot Load Locations

When I loaded the Locations, I got the error below. However, stateID is not a field in the com.bullhornsdk.data.model.entity.core.paybill.Location class. Can you please add it? Thanks.

com.bullhornsdk.data.exception.RestApiException: {"errorMessage":"error persisting an entity of type: Location","errorMessageKey":"errors.cannotPersistEntity","errorCode":500,"errors":[{"detailMessage":"missing required property: stateID","propertyName":"stateID","severity":"ERROR","type":"MISSING_REQUIRED_PROPERTY"}],"entityName":"Location"}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.