I am learning to use the JMockit to test my Restful API.The missing invocation error is abusing me.
The Restful API:
#RestController
public class AgentInfoRest {
#Autowired
AgentInfoRepository agentInfoRepository;
private Logger logger = LoggerFactory.getLogger(AgentInfoRest.class);
#RequestMapping("/allagentInfo")
RestResponse getAllAgentInfo()
{
RestResponse restResponse = new RestResponse();
logger.info("getAllAgentInfo has no request parameter");
Collection<AgentInfo> result = agentInfoRepository.getAllAgents();
if(result.isEmpty())
{
restResponse.setRetCode(-1);
restResponse.setRetMsg("Request success,no such record in db");
}
restResponse.setResult(result);
return restResponse;
}
}
The Test Class:
public class AgentInfoRestTest {
String host = "http://127.0.0.1:8080";
#Test
public void getAllAgentInfoTest(#Mocked final AgentInfoRepository agentInfoRepository) {
RestTemplate restTemplate = new RestTemplate();
RestResponse restResponse = new RestResponse();
AgentInfoRest agentInfoRest = new AgentInfoRest();
new StrictExpectations() {
{
agentInfoRepository.getAllAgents(); result = null; times = 1;
}
};
String url = "/allagentInfo";
ResponseEntity<RestResponse> result = restTemplate.getForEntity(host + url, RestResponse.class);
new FullVerifications() {
{
}
};
}
}
The Error:
mockit.internal.MissingInvocation: Missing invocation of:
com.egoo.dao.repository.freelink.AgentInfoRepository#getAllAgents()
on mock instance: com.egoo.dao.repository.freelink.$Impl_AgentInfoRepository#50a7bc6e
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:253)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: Missing invocation
at com.egoo.dao.rest.freelink.AgentInfoRestTest$1.(AgentInfoRestTest.java:33)
at com.egoo.dao.rest.freelink.AgentInfoRestTest.getAllAgentInfoTest(AgentInfoRestTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:498)
... 7 more
Related
My spark job is throwing Task not serializable at runtime. Can anyone tell me if what i am doing wrong here?
#Component("loader")
#Slf4j
public class LoaderSpark implements SparkJob {
private static final int MAX_VERSIONS = 1;
private final AppProperties props;
public LoaderSpark(
final AppProperties props
) {
this.props = props;
}
#Override
public void run(SparkSession spark, final String... args) throws IOException {
HBaseUtil hBaseUtil = new HBaseUtil(props);
byte[][] prefixes = new byte[][]{toBytes("document"),
toBytes("dataSource"),
toBytes("hold:")};
Filter filter = new MultipleColumnPrefixFilter(prefixes);
Scan scan = new Scan();
scan.addFamily(toBytes("data"));
scan.setCaching(100000);
scan.setMaxVersions(MAX_VERSIONS);
scan.setFilter(filter);
JavaRDD<TestMethod> mapFileJavaRDD
= hBaseUtil.createScanRdd(spark, "TestTable", scan).mapPartitions(tuple -> {
return StreamUtils.asStream(tuple)
.map(this::extractResult)
.filter(Objects::nonNull)
.iterator();
});
Dataset<TestMethod> testDataset = spark.createDataset(mapFileJavaRDD.rdd(), bean(TestMethod.class));
testDataset.limit(100);
}
private TestMethod extractResult(Tuple2<ImmutableBytesWritable, Result> resultTuple) {
TestMethod.TestMethodBuilder testBuilder = TestMethod.builder();
Result result;
result = resultTuple._2();
CdfParser cdfParser = new CdfParser();
List<String> holdingId = new ArrayList<>();
testBuilder.dataSource(Bytes.toString(result.getValue(Bytes.toBytes("data"),
Bytes.toBytes("dataSource"))));
testBuilder.document(cdfParser.fromXml(result.getValue(Bytes.toBytes("data"),
Bytes.toBytes("document"))));
NavigableMap<byte[], byte[]> familyMap = result.getFamilyMap(Bytes.toBytes("data"));
for (byte[] bQunitifer : familyMap.keySet()) {
if (Bytes.toString(bQunitifer).contains("hold:")) {
LOG.info(Bytes.toString(bQunitifer));
holdingId.add(Bytes.toString(bQunitifer));
}
}
testBuilder.holding(holdingId);
return testBuilder.build();
}
}
HERE is the stacktrace:
2020-04-29 12:48:59,837 INFO [Thread-4]o.a.s.d.y.ApplicationMaster: Unregistering ApplicationMaster with FAILED (diag message: User class threw exception: java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:768)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.oclc.googlelinks.spark.SpringSparkJob.main(SpringSparkJob.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.yarn.ApplicationMaster$$anon$2.run(ApplicationMaster.scala:694)
Caused by: org.apache.spark.SparkException: Task not serializable
at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:403)
at org.apache.spark.util.ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(ClosureCleaner.scala:393)
at org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:162)
at org.apache.spark.SparkContext.clean(SparkContext.scala:2326)
at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1.apply(RDD.scala:798)
at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1.apply(RDD.scala:797)
at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)
at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112)
at org.apache.spark.rdd.RDD.withScope(RDD.scala:363)
at org.apache.spark.rdd.RDD.mapPartitions(RDD.scala:797)
at org.apache.spark.api.java.JavaRDDLike$class.mapPartitions(JavaRDDLike.scala:155)
at org.apache.spark.api.java.AbstractJavaRDDLike.mapPartitions(JavaRDDLike.scala:45)
at org.oclc.googlelinks.spark.job.LoaderSpark.run(LoaderSpark.java:79)
at org.oclc.googlelinks.spark.SpringSparkJob.run(SpringSparkJob.java:79)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784)
... 8 more
try adding getter and setters for props
public void setProps(AppProperties props) {
this.props = props;
}
public AppProperties getProps() {
return props;
}
Just make the function extractResult static . In order to call a static method, you don’t need to serialize the class, you need the declaring class to be reachable by the classloader (and it is the case, as the jar archives can be shared among driver and workers).
Thanks to https://www.nicolaferraro.me/2016/02/22/using-non-serializable-objects-in-apache-spark/
When trying to resolve the test described in Where exactly is the NullPointer Exception?, I used a seemingly simpler approach, being the resource test the next:
public class CustomerResourceFunctionalTesting {
private static final String SERVER_URL = "http://localhost:8080/api/v0/";
#Rule
public ExpectedException thrown = ExpectedException.none();
private int createCustomer(String name) {
CustomerDto customerDto = new CustomerDto(name, name + " address");
return new RestBuilder2<Integer>(SERVER_URL).path(CustomerResource.CUSTOMERS)
.body(customerDto).clazz(Integer.class).post().build();
}
private int createCustomer() {
return this.createCustomer("customer1");
}
#Test
public void testReadCustomers() {
List<CustomerDto> customerDtoList = Arrays.asList(new RestBuilder2<CustomerDto[]>
(SERVER_URL).path(CustomerResource.CUSTOMERS).clazz(CustomerDto[].class).get().build());
assertEquals(0, customerDtoList.size());
int id = this.createCustomer();
customerDtoList = Arrays.asList(new RestBuilder2<CustomerDto[]>
(SERVER_URL).path(CustomerResource.CUSTOMERS).clazz(CustomerDto[].class)
.get().build());
assertEquals(1, customerDtoList.size());
this.deleteCustomer(id);
}
private void deleteCustomer(int id) {
new RestBuilder<Object>
(SERVER_URL).path(CustomerResource.CUSTOMERS).path(CustomerResource.CUSTOMER_ID)
.expand(id).delete().build();
}
}
And the RestBuilder a bit different:
public class RestBuilder2<T> {
private RestTemplate restTemplate = new RestTemplate();
private String uri;
private List<Object> expandList;
private Map<String, String> headerValues;
private String authorization = null;
private Object body = null;
private MultiValueMap<String, String> params;
private Class<T> clazz;
private HttpMethod method;
public RestBuilder2(String serverUri) {
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
this.uri = serverUri;
this.expandList = new ArrayList<>();
headerValues = new HashMap<>();
params = new HttpHeaders();
}
public RestBuilder2<T> path(String path) {
this.uri = this.uri + path;
return this;
}
public RestBuilder2<T> expand(Object... values) {
for (Object value : values) {
this.expandList.add(value);
}
return this;
}
public RestBuilder2<T> pathId(int path) {
this.uri = this.uri + "/" + path;
return this;
}
public RestBuilder2<T> pathId(String path) {
this.uri = this.uri + "/" + path;
return this;
}
public RestBuilder2<T> authorization(String authorizationValue) {
this.authorization = authorizationValue;
return this;
}
public RestBuilder2<T> basicAuth(String nick, String pass) {
String auth = nick + ":" + pass;
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
String authHeader = "Basic " + encodedAuth;
this.authorization = authHeader;
return this;
}
public RestBuilder2<T> param(String key, String value) {
this.params.add(key, value);
return this;
}
public RestBuilder2<T> header(String key, String value) {
this.headerValues.put(key, value);
return this;
}
public RestBuilder2<T> body(Object body) {
this.body = body;
return this;
}
public RestBuilder2<T> notError() {
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
return this;
}
public RestBuilder2<T> clazz(Class<T> clazz) {
this.clazz = clazz;
return this;
}
private HttpHeaders headers() {
HttpHeaders headers = new HttpHeaders();
for (String key : headerValues.keySet()) {
headers.set(key, headerValues.get(key));
}
if (authorization != null) {
headers.set("Authorization", authorization);
}
return headers;
}
private URI uri() {
UriComponents uriComponents;
if (params.isEmpty()) {
uriComponents = UriComponentsBuilder.fromHttpUrl(uri).build();
} else {
uriComponents = UriComponentsBuilder.fromHttpUrl(uri).queryParams(params).build();
}
if (!expandList.isEmpty()) {
uriComponents = uriComponents.expand(expandList.toArray());
}
return uriComponents.encode().toUri();
}
public T build() {
if (body != null && !method.equals(HttpMethod.GET)) {
return restTemplate.exchange(this.uri(), method, new HttpEntity<Object>(body, this.headers()), clazz).getBody();
} else {
return restTemplate.exchange(this.uri(), method, new HttpEntity<Object>(this.headers()), clazz).getBody();
}
}
public RestBuilder2<T> post() {
this.method = HttpMethod.POST;
return this;
}
public RestBuilder2<T> get() {
this.method = HttpMethod.GET;
return this;
}
public RestBuilder2<T> put() {
this.method = HttpMethod.PUT;
return this;
}
public RestBuilder2<T> patch() {
this.method = HttpMethod.PATCH;
return this;
}
public RestBuilder2<T> delete() {
this.method = HttpMethod.DELETE;
return this;
}
}
But then I take an error whose trace is:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8080/api/v0/customers": Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:636)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:557)
at account.persistence.resources.RestBuilder2.build(RestBuilder2.java:143)
at account.persistence.resources.CustomerResource2FunctionalTesting.testReadCustomers(CustomerResource2FunctionalTesting.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:159)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:89)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:660)
... 29 more
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
The rest of implied parts of the application is the same as the indicated in the link post, except for not using any RestService.
I think that, in this case, I could not get the NullPointerException, but before I need to resolve the ResourceAccess Exception.
I have developed a simple java program to fetch the data of issues/user stories.
I want to fetch 'description' field of a perticular issue. I have used GET method to get response but I'm getting errors while connecting to JIRA.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class JiraIssueDescription {
public static void main(String[] args) {
try {
URL url = new URL("https://****.atlassian.net/rest/agile/1.0/issue/41459");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("username", "***#abc.com");
conn.setRequestProperty("password", "****");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
When I run the project I get following error
java.net.UnknownHostException: ****.atlassian.net
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
at sun.security.ssl.BaseSSLSocketImpl.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at com.JiraIntegration.bean.JiraIssueDescription.main(JiraIssueDescription.java:24)
Can anyone please help me with the errors. Do I need to implement OAuth ?
UnknownHostException looks like you have a typo in your URL or are facing some proxy issues .
Does it work in your Browser?
It should give you some json in response. Like this:
https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658
You could also test with other tools like curl. Does it work?
curl https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658
Atlassian rest API provides two authentication methods, Basic auth and Oauth. Use this approach to create a valid basic auth header or try the request without parameters.
The following code demonstrates how it should work:
package stack48618849;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.junit.Test;
public class HowToReadFromAnURL {
#Test
public void readFromUrl() {
try (InputStream in = getInputStreamFromUrl("https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658")) {
System.out.println(convertInputStreamToString(in));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Test(expected = RuntimeException.class)
public void readFromUrlWithBasicAuth() {
String user="aUser";
String passwd="aPasswd";
try (InputStream in = getInputStreamFromUrl("https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658",user,passwd)) {
System.out.println(convertInputStreamToString(in));
} catch (Exception e) {
System.out.println("If basic auth is provided, it should be correct: "+e.getMessage());
throw new RuntimeException(e);
}
}
private InputStream getInputStreamFromUrl(String urlString,String user, String passwd) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
String encoded = Base64.getEncoder().encodeToString((user+":"+passwd).getBytes(StandardCharsets.UTF_8));
conn.setRequestProperty("Authorization", "Basic "+encoded);
return conn.getInputStream();
}
private InputStream getInputStreamFromUrl(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
return conn.getInputStream();
}
private String convertInputStreamToString(InputStream inputStream) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString("UTF-8");
}
}
This prints:
{"expand":"renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations","id":"789521","self":"https://jira.atlassian.com/rest/api/2/issue/789521","key":"JSWCLOUD-11658","fields":{"customfield_18232":...
If basic auth is provided, it should be correct: Server returned HTTP response code: 401 for URL: https://jira.atlassian.com/rest/api/2/issue/JSWCLOUD-11658
Instead of a HttpURLConnection way of implementing, you could use Spring's RestTemplate in an efficient manner to solve your problem:
Providing you a piece of code that I use, with the JIRA REST APIs:
Create a RESTClient that you would want to use in conjunction with JIRA REST APIs as like the below:
public class JIRASpringRESTClient {
private static final String username = "fred";
private static final String password = "fred";
private static final String jiraBaseURL = "https://jira.xxx.com/rest/api/2/";
private RestTemplate restTemplate;
private HttpHeaders httpHeaders;
public JIRASpringRESTClient() {
restTemplate = new RestTemplate();
httpHeaders = createHeadersWithAuthentication();
}
private HttpHeaders createHeadersWithAuthentication() {
String plainCredentials = username + ":" + password;
byte[] base64CredentialsBytes = Base64.getEncoder().encode(plainCredentials.getBytes());
String base64Credentials = new String(base64CredentialsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Credentials);
return headers;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public ResponseEntity<String> getJIRATicket(String issueId) {
String url = jiraBaseURL + "issue/" + issueId;
HttpEntity<?> requestEntity = new HttpEntity(httpHeaders);
return restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
}
}
Then you can further re-use these methods as like the below:
public class JIRATicketGet {
public static void main(String... args) {
JIRASpringRESTClient restClient = new JIRASpringRESTClient();
ResponseEntity<String> response = restClient.getJIRATicket("XXX-12345");
System.out.println(response.getBody());
}
}
This will provide the GET response from JIRA, which is in JSON format which can be further manipulated to get the specific field from the GET response with the use of com.fasterxml.jackson.databind.ObjectMapper
Using the JSON that you get in the step above, you can create a POJO class (for example, Ticket) and then use it as follows:
ObjectMapper mapper = new ObjectMapper();
try {
Ticket response = mapper.readValue(response.getBody(), Ticket.class);
} catch (IOException e) {
e.printStackTrace();
}
Hope this helps!
I create an application by using Bluemix's Liberty for Java to connect Cloudant. I found RuntimeException everyday while connecting to my RESTful API. However, I have to restart my application everyday to solve this problem.
An error is shown as follow:
Exception thrown by application class 'org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage:116'
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: Error retrieving server response
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
at [internal classes]
Caused by: org.apache.cxf.interceptor.Fault: Error retrieving server response
at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:163)
... 1 more
Caused by: com.cloudant.client.org.lightcouch.CouchDbException: Error retrieving server response
at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:501)
at com.cloudant.client.org.lightcouch.CouchDbClient.executeToInputStream(CouchDbClient.java:515)
at com.cloudant.client.api.Database.findByIndex(Database.java:361)
at com.cloudant.client.api.Database.findByIndex(Database.java:321)
at th.co.gosoft.rest.TopicService.getHotTopicList(TopicService.java:82)
at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:636)
... 1 more
Caused by: java.net.ProtocolException: Server rejected operation
at sun.net.www.protocol.http.HttpURLConnection.expect100Continue(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(Unknown Source)
at com.cloudant.http.HttpConnection.execute(HttpConnection.java:231)
at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:466)
... 9 more
I use this CloudantClientMgr as follow:
package th.co.gosoft.util;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map.Entry;
import java.util.Set;
import com.cloudant.client.api.ClientBuilder;
import com.cloudant.client.api.CloudantClient;
import com.cloudant.client.api.Database;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class CloudantClientMgr {
private static CloudantClient cloudant = null;
private static Database db = null;
private static String databaseName = "go10_db";
private static String url = "https://xxxxxxxxxx-bluemix.cloudant.com";
private static String user = "xxxxxxxxxx-bluemix";
private static String password = "password";
private static void initClient() {
if (cloudant == null) {
synchronized (CloudantClientMgr.class) {
if (cloudant != null) {
return;
}
try {
cloudant = createClient();
} catch (MalformedURLException e) {
throw new RuntimeException(e.getMessage(), e);
}
System.out.println("cloudant : " + cloudant.serverVersion());
}
}
}
private static CloudantClient createClient() throws MalformedURLException {
String VCAP_SERVICES = System.getenv("VCAP_SERVICES");
String serviceName = null;
CloudantClient client;
if (VCAP_SERVICES != null) {
System.out.println("VCAP_SERVICE");
JsonObject obj = (JsonObject) new JsonParser().parse(VCAP_SERVICES);
Entry<String, JsonElement> dbEntry = null;
Set<Entry<String, JsonElement>> entries = obj.entrySet();
for (Entry<String, JsonElement> eachEntry : entries) {
if (eachEntry.getKey().toLowerCase().contains("cloudant")) {
dbEntry = eachEntry;
break;
}
}
if (dbEntry == null) {
throw new RuntimeException("Could not find cloudantNoSQLDB key in VCAP_SERVICES env variable");
}
obj = (JsonObject) ((JsonArray) dbEntry.getValue()).get(0);
serviceName = (String) dbEntry.getKey();
System.out.println("Service Name - " + serviceName);
obj = (JsonObject) obj.get("credentials");
user = obj.get("username").getAsString();
password = obj.get("password").getAsString();
client = ClientBuilder.account(user)
.username(user)
.password(password)
.build();
} else {
System.out.println("LOCAL");
client = ClientBuilder.url(new URL(url))
.username(user)
.password(password)
.build();
}
return client;
}
public static Database getDB() {
if (cloudant == null) {
initClient();
}
if (db == null) {
try {
db = cloudant.database(databaseName, true);
} catch (Exception e) {
throw new RuntimeException("DB Not found", e);
}
}
return db;
}
private CloudantClientMgr() {
}
}
I use this code to connect CloudantClientMgr as follow:
#Path("topic")
public class TopicService {
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response createTopic(TopicModel topicModel) {
Database db = CloudantClientMgr.getDB();
com.cloudant.client.api.model.Response response = db.save(topicModel);
String result = response.getId();
return Response.status(201).entity(result).build();
}
}
The Cloudant version is 2.4.2
<dependency>
<groupId>com.cloudant</groupId>
<artifactId>cloudant-client</artifactId>
<version>2.4.2</version>
</dependency>
If anyone used to found this problem, please let me know the better solution than I have to restart my application every day.
The problem you describe sounds identical to one that was resolved in version 2.4.1.
I would check to make sure you don't have multiple versions of the cloudant-client included in your application or classpath and that your application is really using version 2.4.2. The line numbers in the stack trace you provide do not match with the source for 2.4.2.
I have a sample JMS messaging application as shown in below snippet. When I executing the program (specifically when starting the connection) I get an UnknowHostException.
The reason for the exception is clientid property get's null.
Application:
public class MessagingTestApp {
private static final String MY_JMS_CONNECTION_FACTORY_NAME = "myJmsFactory";
private static final String EXCHANGE_NAME = "topicExchange";
private static final String JNDI_PROPERTIES_FILE_NAME = "jndi.properties";
private static final String COULD_NOT_LOAD_JNDI_PROPERTIES_MESSAGE = "Could not load JNDI properties....";
private static final boolean NON_TRANSACTED = false;
private static final Logger LOG = Logger.getLogger(MessagingTestApp.class);
public MessagingTestApp() {}
public static void main(String[] args) {
MessagingTestApp messagingTestApp = new MessagingTestApp();
messagingTestApp.runTest();
}
private void runTest() {
try {
Properties properties = new Properties();
properties.load(loadPropertiesFile());
Context context = new InitialContext(properties);
ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup(MY_JMS_CONNECTION_FACTORY_NAME);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(NON_TRANSACTED, Session.AUTO_ACKNOWLEDGE);
Destination destination = (Destination) context.lookup(EXCHANGE_NAME);
MessageProducer messageProducer = session.createProducer(destination);
MessageConsumer messageConsumer = session.createConsumer(destination);
TextMessage message = session.createTextMessage("Hello JMS!");
messageProducer.send(message);
message = (TextMessage) messageConsumer.receive();
System.out.println(message.getText());
connection.close();
context.close();
} catch (Exception e) {
LOG.error(e);
e.printStackTrace();
}
}
private InputStream loadPropertiesFile() {
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader = currentThread.getContextClassLoader();
InputStream propertiesStream = contextClassLoader.getResourceAsStream(JNDI_PROPERTIES_FILE_NAME);
if (propertiesStream != null) {
return propertiesStream;
} else {
System.out.println(COULD_NOT_LOAD_JNDI_PROPERTIES_MESSAGE);
return null;
}
}
}
JNDI properties file:
java.naming.factory.initial = org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory
java.naming.provider.url = src/main/resources/jndi.properties
connectionfactory.myJmsFactory = amqp://admin:admin#clientid/test?
brokerlist = 'tcp://localhost:5672'
destination.topicExchange = amq.topic
Stack-trace:
javax.jms.JMSException: java.net.UnknownHostException: clientid
at org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.connect(ConnectionImpl.java:112)
at org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.start(ConnectionImpl.java:266)
at com.adc.efg.MessagingTestApp.runTest(MessagingTestApp.java:39)
at com.adc.efg.MessagingTestApp.main(MessagingTestApp.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.apache.qpid.amqp_1_0.client.ConnectionException: java.net.UnknownHostException: clientid
at org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:271)
at org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:135)
at org.apache.qpid.amqp_1_0.jms.impl.ConnectionImpl.connect(ConnectionImpl.java:105)
... 8 more
Caused by: java.net.UnknownHostException: clientid
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at org.apache.qpid.amqp_1_0.client.Connection.<init>(Connection.java:159)
... 10 more
I'm new to both JBoss-AMQ and JMS. Much appreciated if anyone can point me out where did I go wrong.
Problem was in JNDI properties file. It should be like below,
java.naming.factory.initial = org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory
java.naming.provider.url = src/main/resources/jndi.properties
connectionfactory.myJmsFactory = amqp://admin:admin#localhost/test?
brokerlist = 'tcp://localhost:5672'
destination.topicExchange = amq.topic