Programmatically retrieve all repositories under my Github account using Jgit - java

I'm having a bit of a challenge with the JGit client. I'm embedding it in a Java App & I'd like to fetch all the repositories under an account on Github and display them. Also to add on, can I create a repository direct on Github using JGit. Like Create a Remote Repository?
I've gone through this link but it seems generic to me. Thanks in advance

The List user repositories API is something you can call from any language (including Java) and is not related to JGit.
GET /users/:username/repos
An example of Java library making those calls would be "GitHub API for Java ", and its java.org.kohsuke.github.GHPerson.java#listRepositories() method
new PagedIterator<GHRepository>(
root.retrieve().asIterator("/users/" + login + "/repos?per_page=" + pageSize,
GHRepository[].class, pageSize))
Once you get the url for those user repos, you can create JGit repos out of them.

I also doing that same Requirement To get List of repositories of a particular user
Try this one you will get All repositories of that user
//Here name means username of GitHub account
public Collection<AuthMsg> getRepos(String name) {
String url = "https://api.github.com/users/"+name+"/repos";
String data = getJSON(url);
System.out.println(data);
Type collectionType = new TypeToken<Collection<AuthMsg>>(){}.getType();
Collection<AuthMsg> enums = new Gson().fromJson(data, collectionType);
return enums;
}
//getJson method
public String getJSON(String url) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
return sb.toString();
}
} catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
//AuthMsg Class
public class AuthMsg {
//"name" which is in json what we get from url
#SerializedName("name")
private String repository;
/**
* #return the repository
*/
public String getRepository() {
return repository;
}
/**
* #param repository the repository to set
*/
public void setRepository(String repository) {
this.repository = repository;
}
}

Related

Exception is java.net.ProtocolException: Invalid HTTP method: PATCH

I am trying to update user metadata by using HttpURLConnection PATCH API.
I had googled and found this useful link which I used.
[https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch][1]
Following are my steps to update user metadata.
Calling database to get user information which need to be
updated, suppose database return 1000 users
.
Calling GET xxx/users/{userId} API 1000 times to check whether
database user exists or not,
Suppose GET xxx/users/{userId} API return 800 active users which
needs to be updated afterwards
Calling PATCH xxx/users/{userId} API 800 times to update user
metadata.
My code working fine if record size is less than or equal to 200-250 but If size gets increase say 1000 then application throwing exception saying
Exception is java.net.ProtocolException: Invalid HTTP method: PATCH
Here is my code.
public static void main(String[] args) throws FileNotFoundException, IOException {
// Here calling DB to get user metadata
List<CEUser> ca = getUserMetada(prop);
// Calling GET users/{userId} API to check whether user exists or not
List<CEUser> activeUsers = getActiveUsers(ca, prop);
// Calling PATCH users/{userId} API to update user metadata
updateUsername(activeUsers, prop);
}
public List<CEUser> getActiveUsers(List<CEUser> CEUsers, Properties prop) {
try {
List<CEUser> activeCEUsers = new ArrayList<>();
for (CEUser ca : CEUsers) {
URL url = new URL(prop.getCeBaseURL() + "users/" + ca.getUserId());
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setRequestProperty("Accept", "application/json");
httpConnection.connect();
if (httpConnection.getResponseCode() == 200)
activeCEUsers.add(ca);
httpConnection.disconnect();
}
return activeCEUsers;
} catch (Exception e) {
System.out.println("Exception occurred in getActiveUsers() method ");
}
}
private static void allowMethods(String... methods) {
try {
Field methodsField = HttpURLConnection.class.getDeclaredField("methods");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL);
methodsField.setAccessible(true);
String[] oldMethods = (String[]) methodsField.get(null);
Set<String> methodsSet = new LinkedHashSet<>(Arrays.asList(oldMethods));
methodsSet.addAll(Arrays.asList(methods));
String[] newMethods = methodsSet.toArray(new String[0]);
methodsField.set(null/*static field*/, newMethods);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public List<CEUser> updateUsername(List<CEUser> ceUsers, Properties prop) {
try {
allowMethods("PATCH");
List<CEUser> updatedUsername = new ArrayList<>();
for (CEUser ca : ceUsers) {
// Construct username
String username = "some static email";
// Construct email into json format to set in body part
String json = constructJson("email", username);
URL url = new URL(prop.getCeBaseURL() + "users/" + ca.getUserId());
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setRequestMethod("PATCH");
httpConnection.setDoOutput(true);
httpConnection.setRequestProperty("Accept-Charset", "UTF-8");
httpConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
try (OutputStream output = httpConnection.getOutputStream()) {
output.write(json.getBytes("UTF-8"));
}
httpConnection.connect();
if (httpConnection.getResponseCode() == 200) {
ca.setUsername(username); // set updated username
updatedUsername.add(ca);
}
httpConnection.disconnect();
}
return updatedUsername;
} catch (Exception e) {
System.out.println("Exception occurred in updateUsername() method");
}
}
Any idea why same code working for 200-250 records but not for 1000 records.
Thanks

Status code 404 when calling spring-boot API, but not for postman or browser

I want to make an API call to a local REST server built with Spring-Boot which is interacting with mongodb. I already checked some posts which I found to this topic, but my problem seems to be a little bit different.
Here are some code snippets which are relevant:
protected static CoreEntity[] sendGET(CoreEntity[] resultList, String path) throws IOException {
path = String.join("%20", path.split(" "));
return handleResponse(resultList, getConnection(path, "Get"));
}
private static HttpURLConnection getConnection(String path, String requestMethod) throws IOException {
URL url = new URL(REQUEST_URL + path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("accept", "application/json");
connection.setConnectTimeout(50000);
connection.setReadTimeout(50000);
connection.setRequestMethod(requestMethod);
initializeGSON();
return connection;
}
private static CoreEntity[] handleResponse(CoreEntity[] resultList, HttpURLConnection connection) {
try {
final int status = connection.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) { // Success
try (InputStreamReader reader = new InputStreamReader(connection.getInputStream()); BufferedReader in = new BufferedReader(reader)) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) { response.append(inputLine); }
reader.close();
in.close();
JSONArray jsonArray = getJSONAsArray(response.toString());
resultList = (CoreEntity[]) Array.newInstance(resultList.getClass().getComponentType(), jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++)
resultList[i] = (CoreEntity) GSON.fromJson(jsonArray.get(i).toString(), resultList.getClass().getComponentType());
} catch (IOException | JSONException e) { e.printStackTrace(); }
} else {
System.out.println("\nRequest failed with error code: " + status);
}
connection.disconnect();
return resultList;
} catch (ConnectException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
The response for http://www.google.com or any other homepage is successful with status code 200. But as soon as I call my API I get an error with status code 404. Strange is that everything works when I am using Postman or the browser. So when I do a get request via postman to the following method (http://localhost:8080/pets/3), I can see the print out and get the data from mongodb, but not for the code above. For the code above nothing happens on server side, no print out, no exception, nothing.
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<T> getById(#PathVariable final long id) {
System.out.println("TEST ===> " + id);
T entity = getService().getById(id);
return entity == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(entity);
}
It seems like my application is not able to find the API, but I already verified that the URL is correct which is why I don’t understand the error code 404.
I also read about package visibility, but my structure looks like the following which is why I don't think that this is the reason.
Package Structure (Don't be confused from name Aerospike)
I've spend way too much time for this now, and I am really desperate for help and hope you can help me or at least point me in the right direction.
Edit
Here is the entire RestController:
#Controller
public abstract class CoreController<S extends CoreService<T>, T extends CoreEntity> {
public static final String SERVER = "http://localhost", PORT = ":8080",
CORE_API = SERVER + PORT + "/"; // controller/v2/
public static final String ID = "id";
private String api;
public CoreController() { }
public CoreController(final String api) { this.api = CORE_API + api; }
#RequestMapping(value = "/{" + ID + "}", method = RequestMethod.GET)
public ResponseEntity<T> getById(#PathVariable final long id) {
System.out.println("TEST ===> " + id);
T entity = getService().getById(id);
return entity == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(entity);
}
public abstract S getService();
}
#Controller
#RequestMapping(value = "pets/")
public class PetController extends CoreController<PetService, Pet> {
#Autowired
protected PetService service;
public static final String API = "pets";
public PetController() { super(API); }
public PetService getService() { return service; }
}
Here the evidence that the spring-boot is listening on 8080 and also postman works with port 8080.
Server print out on start up
I think you missing the slash ("/") in the start and you have duplicate in the end of the exposed value so it's looking for pets//{id} in the controller change to value = { "/pets"}
Anyway, when starting the service syou should see in the logs the exposed uri's

NTLM Authentication Android Studio

I've spent many hours trying to figure out how to perform NTLM authentication on Android Studio with no luck. I realize NTLM is not native to Android. Recently, I have been using the JCIFS library
jcifs.Config.registerSmbURLHandler();
URL url = new URL("https://domain%5cuser:pass#host");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
But I have getting the error
"Unable to find default handler for protocol: https"
The same code works in standard Java. At this point I've exhausted every suggestion I have found and I have no idea what to do.
I'm attempting to resolve the same issue, and came across the following link (class is pasted below in case of link rot):
https://lists.samba.org/archive/jcifs/2013-July/010105.html
I then use the following to force the handler's use:
jcifs.Config.registerSmbURLHandler();
System.setProperty("http.auth.ntlm.domain", domain);
System.setProperty("jcifs.smb.client.domain", domain);
System.setProperty("jcifs.smb.client.username", username);
System.setProperty("jcifs.smb.client.password", password);
System.setProperty("java.protocol.handler.pkgs", "domain.com.package");
I'm having issues, however, as the response comes back empty, so more investigation needs to be done there.
(The copyright notice, etc. have been left off as it kept confusing SO's code block parser)
public class Handler extends URLStreamHandler {
/**
* The default HTTP port (<code>80</code>).
*/
public static final int DEFAULT_HTTP_PORT = 80;
private static final Map PROTOCOL_HANDLERS = new HashMap();
private static final String HANDLER_PKGS_PROPERTY =
"java.protocol.handler.pkgs";
/**
* Vendor-specific default packages. If no packages are specified in
* "java.protocol.handler.pkgs", the VM uses one or more default
* packages, which are vendor specific. Sun's is included below
* for convenience; others could be as well. If a particular vendor's
* package isn't listed, it can be specified in
* "java.protocol.handler.pkgs".
*/
private static final String[] JVM_VENDOR_DEFAULT_PKGS = new String[] {
"sun.net.www.protocol"
};
private static URLStreamHandlerFactory factory;
/**
* Sets the URL stream handler factory for the environment. This
* allows specification of the factory used in creating underlying
* stream handlers. This can be called once per JVM instance.
*
* #param factory The URL stream handler factory.
*/
public static void setURLStreamHandlerFactory(
URLStreamHandlerFactory factory) {
synchronized (PROTOCOL_HANDLERS) {
if (Handler.factory != null) {
throw new IllegalStateException(
"URLStreamHandlerFactory already set.");
}
PROTOCOL_HANDLERS.clear();
Handler.factory = factory;
}
}
/**
* Returns the default HTTP port.
*
* #return An <code>int</code> containing the default HTTP port.
*/
protected int getDefaultPort() {
return DEFAULT_HTTP_PORT;
}
#Override
protected URLConnection openConnection(URL url) throws IOException
{
return this.openConnection(url, null);
}
#Override
protected URLConnection openConnection(URL url, Proxy proxy) throws IOException
{
url = new URL(url, url.toExternalForm(), getDefaultStreamHandler(url.getProtocol()));
final HttpURLConnection urlConnection;
if (proxy == null) {
urlConnection = (HttpURLConnection) url.openConnection();
} else {
urlConnection = (HttpURLConnection) url.openConnection(proxy);
}
return new NtlmHttpURLConnection(urlConnection);
}
private static URLStreamHandler getDefaultStreamHandler(String protocol)
throws IOException {
synchronized (PROTOCOL_HANDLERS) {
URLStreamHandler handler = (URLStreamHandler)
PROTOCOL_HANDLERS.get(protocol);
if (handler != null) return handler;
if (factory != null) {
handler = factory.createURLStreamHandler(protocol);
}
if (handler == null) {
String path = System.getProperty(HANDLER_PKGS_PROPERTY);
StringTokenizer tokenizer = new StringTokenizer(path, "|");
while (tokenizer.hasMoreTokens()) {
String provider = tokenizer.nextToken().trim();
if (provider.equals("jcifs")) continue;
String className = provider + "." + protocol + ".Handler";
try {
Class handlerClass = null;
try {
handlerClass = Class.forName(className);
} catch (Exception ex) { }
if (handlerClass == null) {
handlerClass = ClassLoader.getSystemClassLoader(
).loadClass(className);
}
handler = (URLStreamHandler) handlerClass.newInstance();
break;
} catch (Exception ex) { }
}
}
if (handler == null) {
for (int i = 0; i < JVM_VENDOR_DEFAULT_PKGS.length; i++) {
String className = JVM_VENDOR_DEFAULT_PKGS[i] + "." +
protocol + ".Handler";
try {
Class handlerClass = null;
try {
handlerClass = Class.forName(className);
} catch (Exception ex) { }
if (handlerClass == null) {
handlerClass = ClassLoader.getSystemClassLoader(
).loadClass(className);
}
handler = (URLStreamHandler) handlerClass.newInstance();
} catch (Exception ex) { }
if (handler != null) break;
}
}
if (handler == null) {
throw new IOException(
"Unable to find default handler for protocol: " +
protocol);
}
PROTOCOL_HANDLERS.put(protocol, handler);
return handler;
}
}
}

How to load custom XML feed with Jsoup?

I have a Java-method that gets a feed-document (via http) and then parses the feed (which is not of-type JSON or XML).
This is the method:
public ArrayList<ArrayList<String>> getFeed(String type)
{
String feed = "";
String address = "";
Document file;
/**
* FEED URLs-------\/
*/
switch (type) {
case "news":
address = "https://[domain]/svc/feeds/news/6001?subtree=false&imagesize=medium-square";
break;
case "events":
address = "http://[domain]/svc/feeds/events/6001?subtree=true&imagesize=medium-square&from=%5bfromDate%5d&to=%5btoDate";
}
try {
HttpURLConnection connection = (HttpURLConnection) (new URL(address)).openConnection();
//TODO: #Test
//----------------------------\/--THIS ONE WILL CAUSE ERRORS!!
file = (Document)connection.getContent();
connection.disconnect();
//OUTPUT
feed = file.getElementsByAttribute("pre").text();
stream = new StringReader(feed);
} catch (Exception e) {}
//BEGIN PARSING\\//--THEN OUTPUT//\\
try {
return parse();
} catch (FeedParseException e) {}
//de-fault
return null;
}
It's not working; saying that object:'file' caused NullPointerException.
So how do I increase my precision in debugging something which seems to me to be non-Open-Source.
P.S.: I'm not testing the "events" case so don't worry about the GET-parameters there.
here's my stack-trace:
I don't see how it helps though...
You can pass to Jsoup the URL object directly.
Instead of:
HttpURLConnection connection = (HttpURLConnection) (new URL(address)).openConnection();
//TODO: #Test
//----------------------------\/--THIS ONE WILL CAUSE ERRORS!!
file = (Document)connection.getContent();
connection.disconnect();
do
file = Jsoup //
.connect(address) //
.timeout( 10 * 1000) //
.ignoreContentType(true) //
.get();
Jsoup 1.8.3

Encode String URL in Java

I have this code below that encodes a URL before it is send over the wire (email):
private static String urlFor(HttpServletRequest request, String code, String email, boolean forgot) {
try {
URI url = forgot
? new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(), createHtmlLink(),
"code="+code+"&email="+email+"&forgot=true", null)
: new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(), createHtmlLink(),
"code="+code+"&email="+email, null);
String s = url.toString();
return s;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
/**
* Create the part of the URL taking into consideration if
* its running on dev mode or production
*
* #return
*/
public static String createHtmlLink(){
if (GAEUtils.isGaeProd()){
return "/index.html#ConfirmRegisterPage;";
} else {
return "/index.html?gwt.codesvr=127.0.0.1:9997#ConfirmRegisterPage;";
}
}
The problem with this is that the generated email looks like this:
http://127.0.0.1:8888/index.html%3Fgwt.codesvr=127.0.0.1:9997%23ConfirmRegisterPage;?code=fdc12e195d&email=demo#email.com
The ? mark and # symbol is replaced with %3F and %23 where when the link is opened from the browser it will not open as it is incorrect.
What is the correct way to do this?
You need to combine the query-parts of the url and add the fragment as the correct parameter.
Something like this should work:
private static String urlFor(HttpServletRequest request, String code, String email, boolean forgot) {
try {
URI htmlLink = new URI(createHtmlLink());
String query = htmlLink.getQuery();
String fragment = htmlLink.getFragment();
fragment += "code="+code+"&email="+email;
if(forgot){
fragment += "&forgot=true";
}
URI url = new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(), htmlLink.getPath(),
query, fragment);
String s = url.toString();
return s;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
You can use the Java API method URLEncoder#encode(). Encode the query parameters using the method.
A better API for doing this is the UriBuilder.

Categories

Resources