Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Java][Jersey2] Fix typo and script, Log enhancements, HTTP signature, deserialization #6476

Merged
merged 48 commits into from
May 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
41e97e6
Mustache template should use invokerPackage tag to generate import
sebastien-rosset May 13, 2020
1760f6a
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 13, 2020
3ae466e
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 13, 2020
b628667
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 13, 2020
4dc915c
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 14, 2020
7a207f6
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 16, 2020
776fba6
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 18, 2020
3fac434
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 19, 2020
a96c46b
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 20, 2020
1351fd0
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 21, 2020
ba65735
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 22, 2020
9a0b89e
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 22, 2020
4c84190
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 22, 2020
94ae683
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 22, 2020
aac9f5a
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 23, 2020
93baa3d
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 23, 2020
5c313b4
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 23, 2020
cda8898
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 23, 2020
1f7e5c1
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 24, 2020
bef435e
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 25, 2020
a9cad38
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 26, 2020
877ecfe
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 27, 2020
8c055f5
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 27, 2020
d64f421
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 28, 2020
4d0edfe
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 28, 2020
afeb701
fix typo, fix script issue, add log statement for troubleshooting
sebastien-rosset May 28, 2020
ed5c165
Add java jersey2 samples with OpenAPI doc that has HTTP signature sec…
sebastien-rosset May 28, 2020
7edcb06
Add sample for Java jersey2 and HTTP signature scheme
sebastien-rosset May 28, 2020
762bdb7
Add unit test for oneOf schema deserialization
sebastien-rosset May 29, 2020
c2c6364
Add unit test for oneOf schema deserialization
sebastien-rosset May 29, 2020
4b0d0ca
Add log statements
sebastien-rosset May 29, 2020
65076bb
Add profile for jersey2
sebastien-rosset May 29, 2020
60f98e1
Temporarily disable unit test
sebastien-rosset May 29, 2020
352497b
Temporarily disable unit test
sebastien-rosset May 29, 2020
476eb01
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 29, 2020
40bb8d9
Merge branch 'master' of github.com:CiscoM31/openapi-generator into j…
sebastien-rosset May 29, 2020
8ff6088
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 30, 2020
05d8718
Merge branch 'master' of github.com:CiscoM31/openapi-generator into j…
sebastien-rosset May 30, 2020
ac1a061
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 30, 2020
aa27b72
Merge branch 'master' of github.com:CiscoM31/openapi-generator into j…
sebastien-rosset May 30, 2020
22e6737
fix typo in pom.xml
sebastien-rosset May 30, 2020
38b8568
fix duplicate jersey2 samples
sebastien-rosset May 30, 2020
efec5a8
fix duplicate jersey2 samples
sebastien-rosset May 30, 2020
057f1ca
fix duplicate artifact id
sebastien-rosset May 30, 2020
e94c5c8
fix duplicate jersey2 samples
sebastien-rosset May 30, 2020
99db107
run samples scripts
sebastien-rosset May 31, 2020
8579966
Merge branch 'master' of https://github.com/OpenAPITools/openapi-gene…
sebastien-rosset May 31, 2020
61e947e
Merge branch 'master' of github.com:CiscoM31/openapi-generator into j…
sebastien-rosset May 31, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.openapitools.client;

import org.openapitools.client.model.Mammal;
import org.openapitools.client.model.AppleReq;
import org.openapitools.client.model.BananaReq;
import org.openapitools.client.model.FruitReq;
import org.openapitools.client.model.BasquePig;
import org.openapitools.client.model.Pig;
import org.openapitools.client.model.Whale;
import org.openapitools.client.model.Zebra;
import java.lang.Exception;

import org.junit.*;
import static org.junit.Assert.*;


public class JSONComposedSchemaTest {
JSON json = null;
Mammal mammal = null;

@Before
public void setup() {
json = new JSON();
mammal = new Mammal();
}

/**
* Validate a oneOf schema can be deserialized into the expected class.
* The oneOf schema does not have a discriminator.
*/
@Test
public void testOneOfSchemaWithoutDiscriminator() throws Exception {
// BananaReq and AppleReq have explicitly defined properties that are different by name.
// There is no discriminator property.
String str = "{ \"cultivar\": \"golden delicious\", \"mealy\": false }";
FruitReq o = json.getContext(null).readValue(str, FruitReq.class);
assertTrue(o.getActualInstance() instanceof AppleReq);
}

/**
* Validate a oneOf schema can be deserialized into the expected class.
* The oneOf schema has a discriminator.
*/
@Test
public void testOneOfSchemaWithDiscriminator() throws Exception {
// Mammal can be one of whale, pig and zebra.
// pig has sub-classes.
String str = "{ \"className\": \"whale\", \"hasBaleen\": true, \"hasTeeth\": false }";
/*
DISABLING unit test for now until ambiguity of discriminator is resolved.

// Note that the 'zebra' schema does not have any explicit property defined AND
// it has additionalProperties: true. Hence without a discriminator the above
// JSON payload would match both 'whale' and 'zebra'. This is because the 'hasBaleen'
// and 'hasTeeth' would be considered additional (undeclared) properties for 'zebra'.
Mammal o = json.getContext(null).readValue(str, Mammal.class);
assertTrue(o.getActualInstance() instanceof Whale);

str = "{ \"className\": \"zebra\" }";
o = json.getContext(null).readValue(str, Mammal.class);
assertTrue(o.getActualInstance() instanceof Zebra);

str = "{ \"className\": \"BasquePig\" }";
o = json.getContext(null).readValue(str, Mammal.class);
assertTrue(o.getActualInstance() instanceof BasquePig);
*/
}
}
6 changes: 3 additions & 3 deletions bin/java-petstore-jersey2-java8.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ find samples/client/petstore/java/jersey2-java8 -maxdepth 1 -type f ! -name "REA
java $JAVA_OPTS -jar $executable $ags

# copy additional manually written unit-tests
mkdir samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client
mkdir samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/auth
mkdir samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/model
mkdir -p samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client
mkdir -p samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/auth
mkdir -p samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/model

cp CI/samples.ci/client/petstore/java/test-manual/common/StringUtilTest.java samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/StringUtilTest.java
cp CI/samples.ci/client/petstore/java/test-manual/jersey2/ApiClientTest.java samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/ApiClientTest.java
Expand Down
5 changes: 5 additions & 0 deletions bin/openapi3/java-petstore-jersey2-java8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"library": "jersey2",
"artifactId": "petstore-openapi3-jersey2-java8",
"dateLibrary": "java8"
}
44 changes: 44 additions & 0 deletions bin/openapi3/java-petstore-jersey2-java8.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh

SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"

while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done

if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi

executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"

if [ ! -f "$executable" ]
then
mvn -B clean package
fi

# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
yaml="modules/openapi-generator/src/test/resources/3_0/python-experimental/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml"
ags="generate --artifact-id petstore-openapi3-jersey2-java8 -i $yaml -g java -c bin/openapi3/java-petstore-jersey2-java8.json -o samples/openapi3/client/petstore/java/jersey2-java8 --additional-properties hideGenerationTimestamp=true --additional-properties serverPort=8082 $@"

echo "Removing files and folders under samples/openapi3/client/petstore/java/jersey2-java8/src/main"
rm -rf samples/openapi3/client/petstore/java/jersey2-java8/src/main
find samples/openapi3/client/petstore/java/jersey2-java8 -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
java $JAVA_OPTS -jar $executable $ags

# copy additional manually written unit-tests
mkdir -p samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client
mkdir -p samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/auth
mkdir -p samples/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/model

cp CI/samples.ci/client/petstore/java/test-manual/jersey2-java8/JSONTest.java samples/openapi3/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/JSONTest.java
cp CI/samples.ci/client/petstore/java/test-manual/jersey2-java8/JSONComposedSchemaTest.java samples/openapi3/client/petstore/java/jersey2-java8/src/test/java/org/openapitools/client/JSONComposedSchemaTest.java
1 change: 1 addition & 0 deletions bin/utils/ensure-up-to-date
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ declare -a samples=(
"${root}/bin/python-server-all.sh"
"${root}/bin/openapi3/python-petstore.sh"
"${root}/bin/openapi3/python-experimental-petstore.sh"
"${root}/bin/openapi3/java-petstore-jersey2-java8.sh"
"${root}/bin/php-petstore.sh"
"${root}/bin/php-silex-petstore-server.sh"
"${root}/bin/php-symfony-petstore.sh"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import org.glassfish.jersey.logging.LoggingFeature;
import org.apache.commons.io.FileUtils;
import org.glassfish.jersey.filter.LoggingFilter;
{{/supportJava6}}
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
Expand Down Expand Up @@ -73,6 +75,8 @@ public class ApiClient {
protected Map<String, String> defaultHeaderMap = new HashMap<String, String>();
protected Map<String, String> defaultCookieMap = new HashMap<String, String>();
protected String basePath = "{{{basePath}}}";
private static final Logger log = Logger.getLogger(ApiClient.class.getName());

protected List<ServerConfiguration> servers = new ArrayList<ServerConfiguration>({{#servers}}{{#-first}}Arrays.asList(
{{/-first}} new ServerConfiguration(
"{{{url}}}",
Expand Down Expand Up @@ -928,6 +932,9 @@ public class ApiClient {
}
} catch (Exception ex) {
// failed to deserialize, do nothing and try next one (schema)
// Logging the error may be useful to troubleshoot why a payload fails to match
// the schema.
log.log(Level.FINE, "Input data does not match schema '" + schemaName + "'", ex);
}
} else {// unknown type
throw new ApiException(schemaType.getClass() + " is not a GenericType and cannot be handled properly in deserialization.");
Expand All @@ -938,7 +945,7 @@ public class ApiClient {
if (matchCounter > 1 && "oneOf".equals(schema.getSchemaType())) {// more than 1 match for oneOf
throw new ApiException("Response body is invalid as it matches more than one schema (" + StringUtil.join(matchSchemas, ", ") + ") defined in the oneOf model: " + schema.getClass().getName());
} else if (matchCounter == 0) { // fail to match any in oneOf/anyOf schemas
throw new ApiException("Response body is invalid as it doens't match any schemas (" + StringUtil.join(schema.getSchemas().keySet(), ", ") + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
throw new ApiException("Response body is invalid as it does not match any schemas (" + StringUtil.join(schema.getSchemas().keySet(), ", ") + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
} else { // only one matched
schema.setActualInstance(result);
return schema;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -15,6 +17,8 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>xmlAnnotation}}
@JsonDeserialize(using={{classname}}.{{classname}}Deserializer.class)
public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-implements}}, {{{.}}}{{/vendorExtensions.x-implements}} {
private static final Logger log = Logger.getLogger({{classname}}.class.getName());

public static class {{classname}}Deserializer extends StdDeserializer<{{classname}}> {
public {{classname}}Deserializer() {
this({{classname}}.class);
Expand All @@ -37,7 +41,8 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
ret.setActualInstance(deserialized);
return ret;
} catch (Exception e) {
// deserialization failed, continue
// deserialization failed, continue, log to help debugging
log.log(Level.FINER, "Input data does not match '{{classname}}'", e);
}

{{/anyOf}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.List;
import java.security.spec.AlgorithmParameterSpec;
import java.security.InvalidKeyException;

import org.tomitribe.auth.signatures.Algorithm;
import org.tomitribe.auth.signatures.Signer;
Expand Down Expand Up @@ -204,7 +205,7 @@ public class HttpSignatureAuth implements Authentication {
* @throws InvalidKeyException Unable to parse the key, or the security provider for this key
* is not installed.
*/
public void setPrivateKey(Key key) throws InvalidKeyException {
public void setPrivateKey(Key key) throws InvalidKeyException, ApiException {
if (key == null) {
throw new ApiException("Private key (java.security.Key) cannot be null");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -15,6 +17,8 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>xmlAnnotation}}
@JsonDeserialize(using={{classname}}.{{classname}}Deserializer.class)
public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-implements}}, {{{.}}}{{/vendorExtensions.x-implements}} {
private static final Logger log = Logger.getLogger({{classname}}.class.getName());

public static class {{classname}}Deserializer extends StdDeserializer<{{classname}}> {
public {{classname}}Deserializer() {
this({{classname}}.class);
Expand All @@ -35,8 +39,10 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
try {
deserialized = tree.traverse(jp.getCodec()).readValueAs({{{.}}}.class);
match++;
log.log(Level.FINER, "Input data matches schema '{{{.}}}'");
} catch (Exception e) {
// deserialization failed, continue
log.log(Level.FINER, "Input data does not match schema '{{{.}}}'", e);
}

{{/oneOf}}
Expand Down
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,18 @@
<module>samples/client/petstore/java/jersey2-java8</module>
</modules>
</profile>
<profile>
<id>java-client-openapi3-jersey2-java8</id>
<activation>
<property>
<name>env</name>
<value>java</value>
</property>
</activation>
<modules>
<module>samples/openapi3/client/petstore/java/jersey2-java8</module>
</modules>
</profile>
<profile>
<id>java-client-okhttp-gson</id>
<activation>
Expand Down Expand Up @@ -1252,6 +1264,7 @@
<module>samples/client/petstore/java/feign10x</module>
<module>samples/client/petstore/java/jersey1</module>
<module>samples/client/petstore/java/jersey2-java8</module>
<module>samples/openapi3/client/petstore/java/jersey2-java8</module>
<module>samples/client/petstore/java/okhttp-gson</module>
<module>samples/client/petstore/java/retrofit2</module>
<module>samples/client/petstore/java/retrofit2rx</module>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import org.glassfish.jersey.logging.LoggingFeature;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
Expand Down Expand Up @@ -60,6 +62,8 @@ public class ApiClient {
protected Map<String, String> defaultHeaderMap = new HashMap<String, String>();
protected Map<String, String> defaultCookieMap = new HashMap<String, String>();
protected String basePath = "http://petstore.swagger.io:80/v2";
private static final Logger log = Logger.getLogger(ApiClient.class.getName());

protected List<ServerConfiguration> servers = new ArrayList<ServerConfiguration>(Arrays.asList(
new ServerConfiguration(
"http://petstore.swagger.io:80/v2",
Expand Down Expand Up @@ -845,6 +849,9 @@ public AbstractOpenApiSchema deserializeSchemas(Response response, AbstractOpenA
}
} catch (Exception ex) {
// failed to deserialize, do nothing and try next one (schema)
// Logging the error may be useful to troubleshoot why a payload fails to match
// the schema.
log.log(Level.FINE, "Input data does not match schema '" + schemaName + "'", ex);
}
} else {// unknown type
throw new ApiException(schemaType.getClass() + " is not a GenericType and cannot be handled properly in deserialization.");
Expand All @@ -855,7 +862,7 @@ public AbstractOpenApiSchema deserializeSchemas(Response response, AbstractOpenA
if (matchCounter > 1 && "oneOf".equals(schema.getSchemaType())) {// more than 1 match for oneOf
throw new ApiException("Response body is invalid as it matches more than one schema (" + StringUtil.join(matchSchemas, ", ") + ") defined in the oneOf model: " + schema.getClass().getName());
} else if (matchCounter == 0) { // fail to match any in oneOf/anyOf schemas
throw new ApiException("Response body is invalid as it doens't match any schemas (" + StringUtil.join(schema.getSchemas().keySet(), ", ") + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
throw new ApiException("Response body is invalid as it does not match any schemas (" + StringUtil.join(schema.getSchemas().keySet(), ", ") + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
} else { // only one matched
schema.setActualInstance(result);
return schema;
Expand Down
21 changes: 21 additions & 0 deletions samples/openapi3/client/petstore/java/jersey2-java8/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# exclude jar for gradle wrapper
!gradle/wrapper/*.jar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# build files
**/target
target
.gradle
build
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator

# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.

# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs

# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux

# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux

# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
Loading