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!
Good day Pals,
I am new to Springboot and having problems testing my PDF uploader spring controller endpoint.
The rest endpoint works when tested via postman, but not in my unit test.
I am using a spring boot application with the following key components and problem is:
org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:251)
2016-06-09 19:03:03,359 4198 [main] DEBUG o.s.t.c.w.ServletTestExecutionListener - Resetting RequestContextHolder for test context [DefaultTestContext#646be2c3 testClass = PDFUploadControllerTest, testInstance = x.y.z.rest.controller.PDFUploadControllerTest#2b44d6d0, testMethod = testHandleFileUpload#PDFUploadControllerTest, testException = java.lang.AssertionError: Status expected:<200> but was:<400>, mergedContextConfiguration = [WebMergedContextConfiguration#797badd3 testClass = PDFUploadControllerTest, locations = '{}', classes = '{class x.y.z.rest.PresentationConfiguration, class x.y.z.rest.controller.MockDomainConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]].
java.lang.AssertionError: Status
Expected :200
Actual :400
Please, see some code and stacktrace below ... I have been banging my head on the wall all day, debugging using all online references but NO luck ....
Your help will be most appreciated. Thanks
Application
#EnableAutoConfiguration()
public class Application {
public static void main(String[] args) {
SpringApplication.run(
new Object[]{
DomainConfiguration.class,
PresentationConfiguration.class
},
args);
}
}
DomainConfiguration
#Configuration
#EnableAutoConfiguration()
#ComponentScan(basePackages = {
"x.y.z.rest.domain",
"x.y.z.rest.service",
"x.y.z.rest.util",
"x.y.z.rest.repository"
})
public class DomainConfiguration {
#Autowired(required = true)
public void configeJackson(ObjectMapper jackson2ObjectMapper) {
jackson2ObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
}
}
PresentationConfiguration
#Configuration
#ComponentScan(basePackages = {"x.y.z.rest.controller"})
public class PresentationConfiguration {
}
## RestController
#RestController
public class PDFUploadController {
#Autowired
public void setUploadService(UploadService uploadService) {
this.uploadService = uploadService;
}
private UploadService uploadService;
#RequestMapping(value="/upload", method=RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public #ResponseBody String handleFileUpload(
#RequestParam("file") MultipartFile file,#RequestParam String a,#RequestParam String b,#RequestParam String c, #RequestParam String d,#RequestParam String e) throws Exception{
java.io.InputStream inputStream =null;
if (!file.isEmpty() && checkContentType(file.getContentType())) {
try {
DBObject dbObject = new BasicDBObject();
//populate DBObject
inputStream = file.getInputStream();
uploadService.uploadFile(inputStream,file.getOriginalFilename(),file.getContentType(),dbObject);
return "success";
} catch (Exception e) {
return "You failed to upload " + file.getOriginalFilename() + " => " + e.getMessage();
}
finally {
if(inputStream!=null) {
inputStream.close();
}
}
} else {
return "You failed to upload " + file.getOriginalFilename() + " as it is an invalid file.";
}
}
}
##### Unit Test Class for Controller
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {
PresentationConfiguration.class,
MockDomainConfiguration.class})
#WebAppConfiguration
public class PDFUploadControllerTest {
#Autowired
private WebApplicationContext webApplicationContext;
#Autowired
private UploadService uploadService;
private MockMvc mockMvc;
#Autowired
private ObjectMapper mapper;
private RestDocumentationResultHandler document;
#Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.build();
}
#After
public void resetMocks() {
reset(uploadService);
}
#Test
public void testHandleFileUpload() throws Exception {
FileInputStream fileInputStream = null;
MockMultipartFile mockMultipartFile = null;
try {
File file = new File("//Users//olatom//Desktop//testFile4Upload.pdf");
// create FileInputStream object
fileInputStream = new FileInputStream(file);
System.out.println("# File input stream for PDF : " + fileInputStream);
byte fileContent[] = new byte[(int) file.length()];
// Reads up to certain bytes of data from this input stream into an array of bytes.
fileInputStream.read(fileContent);
//create string from byte array
String pdfContent = new String(fileContent);
//mockMultipartFile = new MockMultipartFile("upload", file.getName(), "multipart/form-data", fileInputStream);
mockMultipartFile = new MockMultipartFile("file", fileInputStream);
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", "265001916915724");
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
//mockMvc.perform(fileUpload("/upload")
// .file(mockMultipartFile)
// .param("a", "1234").param("b", "PX1234").param("c", "100").param("d", "120")
// .contentType(MediaType.MULTIPART_FORM_DATA))
// .andExpect(status().isOk());
// mockMvc.perform(fileUpload("/upload")).andExpect(status().isOk());
//mockMvc.perform(fileUpload("/upload").file(mockMultipartFile)).andExpect(status().isOk());
mockMvc.perform(
fileUpload("/upload")
.content(mockMultipartFile.getBytes())
.param("a", "1234").param("b", "PX1234").param("c", "100").param("d", "120")
.contentType(mediaType)
)
.andExpect(status().isOk());
} catch (FileNotFoundException e) {
System.out.println("File not found" + e);
} catch (IOException ioe) {
System.out.println("IO Exception while reading file " + ioe);
} catch (Exception exc) {
} finally {
// close the streams using close method
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException ioe) {
System.out.println("Error while closing stream: " + ioe);
}
}
}
}
####### MockDomainConfiguration #####
/**
* Create Mockito mocks for the service classes.
* For this to work the #EnableAutoConfiguration annotation below also has to exclude JPA Autoconfiguration.
*/
#Configuration
#EnableAutoConfiguration()
public class MockDomainConfiguration {
#Bean
public UploadService mockUploadService() {
return mock(UploadService.class);
}
}
## MY ERROR
When I run the junit test in Intellij I get the following error:
2016-06-09 19:03:03,331 4170 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - DispatcherServlet with name '' processing POST request for [/upload]
2016-06-09 19:03:03,342 4181 [main] DEBUG o.s.b.a.e.m.EndpointHandlerMapping - Looking up handler method for path /upload
2016-06-09 19:03:03,343 4182 [main] DEBUG o.s.b.a.e.m.EndpointHandlerMapping - Did not find handler method for [/upload]
2016-06-09 19:03:03,343 4182 [main] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /upload
2016-06-09 19:03:03,344 4183 [main] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]
2016-06-09 19:03:03,344 4183 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'PDFUploadController'
2016-06-09 19:03:03,352 4191 [main] DEBUG o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Error resolving argument [0] [type=org.springframework.web.multipart.MultipartFile]
HandlerMethod details:
Controller [x.y.z.rest.controller.PDFUploadController]
Method [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]
org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:251)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
at x.y.z.rest.controller.PDFUploadControllerTest.testHandleFileUpload(PDFUploadControllerTest.java:140)
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:497)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
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:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
2016-06-09 19:03:03,353 4192 [main] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
2016-06-09 19:03:03,354 4193 [main] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
2016-06-09 19:03:03,354 4193 [main] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public java.lang.String x.y.z.rest.controller.PDFUploadController.handleFileUpload(org.springframework.web.multipart.MultipartFile,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]: org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
2016-06-09 19:03:03,355 4194 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Null ModelAndView returned to DispatcherServlet with name '': assuming HandlerAdapter completed request handling
2016-06-09 19:03:03,355 4194 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Successfully completed request
2016-06-09 19:03:03,359 4198 [main] DEBUG o.s.t.c.s.AbstractDirtiesContextTestExecutionListener - After test method: context [DefaultTestContext#646be2c3 testClass = PDFUploadControllerTest, testInstance = x.y.z.rest.controller.PDFUploadControllerTest#2b44d6d0, testMethod = testHandleFileUpload#PDFUploadControllerTest, testException = java.lang.AssertionError: Status expected:<200> but was:<400>, mergedContextConfiguration = [WebMergedContextConfiguration#797badd3 testClass = PDFUploadControllerTest, locations = '{}', classes = '{class x.y.z.rest.PresentationConfiguration, class x.y.z.rest.controller.MockDomainConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]], class annotated with #DirtiesContext [false] with mode [null], method annotated with #DirtiesContext [false] with mode [null].
2016-06-09 19:03:03,359 4198 [main] DEBUG o.s.t.c.w.ServletTestExecutionListener - Resetting RequestContextHolder for test context [DefaultTestContext#646be2c3 testClass = PDFUploadControllerTest, testInstance = x.y.z.rest.controller.PDFUploadControllerTest#2b44d6d0, testMethod = testHandleFileUpload#PDFUploadControllerTest, testException = java.lang.AssertionError: Status expected:<200> but was:<400>, mergedContextConfiguration = [WebMergedContextConfiguration#797badd3 testClass = PDFUploadControllerTest, locations = '{}', classes = '{class x.y.z.rest.PresentationConfiguration, class x.y.z.rest.controller.MockDomainConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]].
java.lang.AssertionError: Status
Expected :200
Actual :400
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:655)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at x.y.z.rest.controller.PDFloadControllerTest.testHandleFileUpload(PDFUploadControllerTest.java:146)
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:497)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
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:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Your help will be most appreciated.
I am using the HttpURLConnection class to connect to external web service from eclipse, then I am getting a error message "Connection Refused"
public class TestConnection {
static {
//for localhost testing only
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("localhost")) {
return true;
}
return false;
}
});
}
public static void main(String[] args)
{
HttpURLConnection urlConnection;
try {
//https get method with required parameters
// XMLHttpRequest s1 = new XMLHttpRequest ();
urlConnection = (HttpURLConnection) ((new URL("https://google.com").openConnection()));
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("User-Agent", "");
int HTTPS_RESPONSE_CODE = urlConnection.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
String HTTPS_RESULT=response.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
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)
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 TestConnection.main(TestConnection.java:19)
But If i try to connect to the same site from a browser I am able to get a response from the service. Can you please let me know if there is a work around?
By default, the HttpURLConnection class will not allow localhost as the hostname. You need to define a custom hostname verifier which will allow localhost. You can place this code into a static block at the top of the class where you intend to use HttpURLConnection:
public final class YourClassName {
static {
//for localhost testing only
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("localhost")) {
return true;
}
return false;
}
});
}
// use HttpURLConnection here ...
}
Please find the working code,
PROXY_SERVER set to a valid proxy server and port for http I am using is 8080
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_SERVER, PROXY_PORT));
And when you establish the connection pass the proxy as an argument.
urlConnection = (HttpURLConnection) ((new URL(URI).openConnection(proxy)));
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
A similar question has been asked before on this forum, but the accepted answer hasn't been helpful to me. My server has a Kerberos keytab file that I'd like to use to validate a service ticket sent by a client.
Following Sun's documentation and sample code scattered elsewhere this is what I currently have:
Client requests a service ticket from the KDC for MYSPN
Client sends the file to the Service Server to request access to the service.
Server grants access after validating service ticket with keytab for MYSPN it already has.
I'm having trouble getting #3 to work. The specific error I get is:
GSSException: No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT credentials failed!)
at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:100)
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:128)
at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:200)
at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:231)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:319)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at cms.gssapi.Server$1.run(Server.java:188)
at cms.gssapi.Server$1.run(Server.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:357)
at cms.gssapi.Server.acceptSecurityContext(Server.java:182)
at cms.gssapi.Server.main(Server.java:59)
Caused by: javax.security.auth.login.LoginException: Unable to obtain Princpal Name for authentication
at com.sun.security.auth.module.Krb5LoginModule.promptForName(Krb5LoginModule.java:750)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:646)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:559)
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:616)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:784)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203)
at javax.security.auth.login.LoginContext$5.run(LoginContext.java:721)
at javax.security.auth.login.LoginContext$5.run(LoginContext.java:719)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokeCreatorPriv(LoginContext.java:718)
at javax.security.auth.login.LoginContext.login(LoginContext.java:590)
at sun.security.jgss.GSSUtil.login(GSSUtil.java:264)
at sun.security.jgss.krb5.Krb5Util.getKeys(Krb5Util.java:202)
at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:95)
at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:93)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:92)
... 11 more
This is a snippet of the server code that tries to validate the client's service ticket using keytab:
public static void main( String[] args) {
Properties props = new Properties();
props.load( new FileInputStream( "server.properties"));
System.setProperty( "sun.security.krb5.debug", "true");
System.setProperty( "java.security.krb5.realm", props.getProperty( "realm"));
System.setProperty( "java.security.krb5.kdc", props.getProperty( "kdc"));
System.setProperty( "java.security.auth.login.config", "./jaas.conf");
System.setProperty( "javax.security.auth.useSubjectCredsOnly", "false");
krb5Oid = new Oid( "1.2.840.113554.1.2.2");
Server server = new Server();
server.login();
byte serviceTicket[] = readClientTicketFromFile();
String clientName = server.acceptSecurityContext(serviceTicket);
}
private static byte[] readClientTicketFromFile() throws IOException {
BufferedReader in = new BufferedReader( new FileReader( "serviceticket.token"));
String str;
StringBuffer buffer = new StringBuffer();
while ((str = in.readLine()) != null) {
buffer.append( str + "\n");
}
in.close();
BASE64Decoder decoder = new BASE64Decoder();
return decoder.decodeBuffer( buffer.toString());
}
private static Oid krb5Oid;
private Subject login() throws LoginException {
LoginContext loginCtx = null;
loginCtx = new LoginContext( "Server", new LoginCallbackHandler(null,null));
System.out.println("Attempting to do Login...");
loginCtx.login();
Subject ret_sub = loginCtx.getSubject();
return ret_sub;
}
private String acceptSecurityContext( final byte[] serviceTicket)
throws GSSException {
krb5Oid = new Oid( "1.2.840.113554.1.2.2");
return Subject.doAs( subject, new PrivilegedAction<String>() {
public String run() {
try {
GSSManager manager = GSSManager.getInstance();
GSSContext context = manager.createContext( (GSSCredential) null);
context.acceptSecContext( serviceTicket, 0, serviceTicket.length);
return context.getSrcName().toString();
}
catch ( Exception e) {
e.printStackTrace();
return null;
}
}
});
}
Here is my server.properties
realm=MYREALM
kdc=192.168.1.1
and jaas.conf file
Client {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=false
useKeyTab=false
storeKey=false
isInitiator=true
debug=true
;
};
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
doNotPrompt=true
isInitiator=false
keyTab="/etc/krb5.keytab"
principal="MYSPN/host.domain.com#MYREALM"
debug=true
;
};
I'm sure the service ticket is valid because the server can authenticate if I provide password for the service account, but I want to use a keytab file instead of password.